JS

不积跬步之Event Loop 以及宏任务 微任务

2021-09-02  本文已影响0人  雨飞飞雨
event loop

讲到event loop事件循环,网上最好的资源应该就是Philip Roberts的演讲《Help, I'm stuck in an event-loop》)
以及 深入事件环(In The Loop)Jake Archibald@JSconf 2018 (我放的是B站的连接,up主已经做好了翻译) 阮一峰写的JavaScript 运行机制详解:再谈Event Loop 同样也是基于 上面第一篇文章。看完以后大受启发,学习这些资源还是应该去源头上看。

我希望这篇文章可以回答以下问题:

  1. event loop 它的执行顺序是什么?
  2. 什么是宏任务和微任务以及他们的区别?
  3. 实现宏任务和微任务的方式都有哪些?

我们开始吧:

1.什么是事件循环 event loop 呢?

它的组成部分包括如下:

实际上上图是在2014年的时候出的,距离我们现在微任务的场景已经略微过时。我手绘了如下的图片来说明我们现在完整的:

WechatIMG67.jpeg

它的执行顺序如下:

微任务会在下一轮宏任务执行之前先执行。
微任务会一直执行,直到微任务队列清空为止,这里也有可能 无限执行下去,有这种风险。

2.什么是宏任务和微任务以及他们的区别?

宏任务:

一个宏任务就是由执行诸如从头执行一段程序、执行一个事件回调或一个interval/timeout 被触发之类的标准机制而被调度的任意 JavaScript 代码。这些都在 任务队列(task queue)上被调度。

在以下时机,任务会被添加到任务队列:

事件循环驱动你的代码按照这些任务排队的顺序,一个接一个地处理它们。在当前迭代轮次中,只有那些当事件循环过程开始时 已经处于任务队列中 的任务会被执行。其余的任务不得不等待到下一次迭代。

微任务

起初微任务和任务之间的差异看起来不大。它们很相似;都由位于某个队列的JavaScript 代码组成并在合适的时候运行。但是,只有在迭代开始时队列中存在的任务才会被事件循环一个接一个地运行,这和处理微任务队列是殊为不同的。

有两点关键的区别。

首先,每当一个任务存在,事件循环都会检查该任务是否正把控制权交给其他 JavaScript 代码。如若不然,事件循环就会运行微任务队列中的所有微任务。接下来微任务循环会在事件循环的每次迭代中被处理多次,包括处理完事件和其他回调之后。

其次,如果一个微任务通过调用 queueMicrotask(), 向队列中加入了更多的微任务,则那些新加入的微任务 会早于下一个任务运行 。这是因为事件循环会持续调用微任务直至队列中没有留存的,即使是在有更多微任务持续被加入的情况下。

3.实现宏任务和微任务的方式都有哪些?

微任务 宏任务
MutationObserver script
Promise.then()或catch() setTimeout
Promise为基础开发的其它技术,比如fetch API setInterval
V8的垃圾回收过程 setImmediate
Node独有的process.nextTick I/O
queueMicrotask UI rendering

学习的资源:

Philip Roberts的演讲《Help, I'm stuck in an event-loop》)

深入事件环(In The Loop)Jake Archibald@JSconf 2018

MDN 在 JavaScript 中通过 queueMicrotask() 使用微任务

深入:微任务与Javascript运行时环境

上一篇下一篇

猜你喜欢

热点阅读