浏览器工作原理与实践--消息队列和事件循环:页面是怎么“活”起来的

前面我们讲到了每个渲染进程都有一个主线程,并且主线程非常繁忙,既要处理DOM,又要计算样式,还要处理布局,同时还需要处理JavaScript任务以及各种输入事件。要让这么多不同类型的任务在主线程中有条不紊地执行,这就需要一个系统来统筹调度这些任务,这个统筹调度系统就是我们今天要讲的消息队列和事件循环系统。

在写这篇文章之前,我翻阅了大量的资料,却发现没有一篇文章能把消息循环系统给讲清楚的,所以我决定用一篇文章来专门介绍页面的事件循环系统。事件循环非常底层且非常重要,学会它能让你理解页面到底是如何运行的, 所以在本篇文章中,我们会将页面的事件循环给梳理清楚、讲透彻。

为了能让你更加深刻地理解事件循环机制,我们就从最简单的场景来分析,然后带你一步步了解浏览器页面主线程是如何运作的。

需要说明的是,文章中的代码我会采用C++来示范。如果你不熟悉C++,也没有关系,这里并没有涉及到任何复杂的知识点,只要你了解JavaScript或Python,你就会看懂。

使用单线程处理安排好的任务

我们先从最简单的场景讲起,比如有如下一系列的任务:

  • 任务1:1+2

  • 任务2:20/5

  • 任务3:7*8

  • 任务4:打印出任务1、任务2、任务3的运算结果

现在要在一个线程中去执行这些任务,通常我们会这样编写代码:

void MainThread(){
     int num1 = 1+2; //任务1
     int num2 = 20/5; //任务2
     int num3 = 7*8; //任务3
     print("最终计算的值为:%d,%d,%d",num1,num2,num3); //任务4
  }

在上面的执行代码中,我们把所有任务代码按照顺序写进主线程里,等线程执行时,这些任务会按照顺序在线程中依次被执行;等所有任务执行完成之后,线程会自动退出。可以参考下图来直观地理解下其执行过程:

第一版:线程的一次执行

在线程运行过程中处理新任务

但并不是所有的任务都是在执行之前统一安排好的,大部分情况下,新的任务是在线程运行过程中产生的。比如在线程执行过程中,又接收到了一个新的任务要求计算“10+2”,那上面那种方式就无法处理这种情况了。

要想在线程运行过程中,能接收并执行新的任务,就需要采用事件循环机制。我们可以通过一个for循环语句来监听是否有新的任务,如下面的示例代码:

//GetInput
//等待用户从键盘输入一个数字,并返回该输入的数字
int GetInput(){
    int input_number = 0;
    cout<<"请输入一个数:";
    cin>>inpu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

echoecho_tongtong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值