事件循环机制的理解

事件循环机制的理解

任务队列

所有的任务可以分为同步任务和异步任务,
同步任务:就是立即执行的任务,同步任务一般会直接进入到主线程中执行;
异步任务:就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过事件队列的机制来进行协调。

同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 事件队列。主线程内的任务执行完毕为空,会去把事件队列读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 事件循环。

在事件循环中,其关键的步骤可以总结如下:

选择最先进入队列的任务( oldest task ),如果有则执行(一次)
检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue
更新 render
主线程重复执行上述步骤

什么是 microtasks ?

任务分为两大类, 分别是 Macro Task (宏任务)和 Micro Task(微任务), 并且每个宏任务结束后, 都要清空所有的微任务。

(macro)task 主要包含:setTimeout、setInterval

microtask主要包含:Promise、MutaionObserver、process.nextTick

setTimeout/Promise 等就是任务源,而进入任务队列的是由他们指定的具体执行任务。来自不同任务源的任务会进入到不同的任务队列。其中 setTimeout 与 setInterval 是同源的。

分析示例代码

举一个例子,下面我们可以按照上面的知识点,一步步执行解析下面的例子。

 console.log('1');

setTimeout(function() {
  console.log('2');
}, 0);

Promise.resolve().then(function() {
  console.log('3');
}).then(function() {
  console.log('4');
});

console.log('5');

先猜测一下这段代码的输出顺序是什么,本文下面的部分会为你答疑解惑。

1.整体 script 作为第一个宏任务进入主线程,遇到 console.log,输出1
2.遇到 setTimeout,其回调函数被分发到宏任务 Event Queue 中
3.遇到 Promise,其 then函数被分到到微任务 Event Queue 中,记为 then1,
4.之后又遇到4.了 then 函数,将其分到微任务 Event Queue 中,记为 then2
5.遇到 console.log,输出5

1.执行微任务,首先执行then1,输出3, 然后执行 then2,输出 4,这样就清空了所有微任务
2.执行 setTimeout 任务,输出 2,至此,输出的顺序是:1,5,3,4,2
如下图:
在这里插入图片描述

注意:
从规范来看,microtask 优先于 task 执行,所以如果有需要优先执行的逻辑,放入microtask 队列会比 task 更早的被执行。

最后的最后,记住,JavaScript 是一门单线程语言,异步操作都是放到事件循环队列里面,等待主执行栈来执行的,并没有专门的异步执行线程。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值