3个框框带你理解EventLoop

239 阅读4分钟

1、事件循环

大家都知道JavaScript是一门单线程语言

大白话讲一下吧:什么是单线程呢,就是主线程在执行代码时,只能从上往下一行一行执行,如果执行到某一行花费了很长时间,那么,呵呵,没办法,后面的代码只能等着,如果执行到某一行,代码出错了,呵呵,后面的也得不到执行。

但是,这样肯定不行的。所以JavaScript引入了同步异步的概念,把比较耗时的代码放到异步API中执行,不要去阻塞主线程。也就有了**事件循环(Event Loop)**的概念

事件循环(Event Loop):先会执行栈中的内容,栈中内容执行后执行微任务,微任务清空后再执行宏任务,宏任务会在栈中执行,不停的循环. 如果还是不懂概念,参考这里

2、用三个框框解释Event Loop

不知道大家遇到过js执行顺序的问题,什么样的组合都有,主要成员有以下几个

  • setTimeout
  • Promise
  • setImmediate
  • Process.nextTick()

每次打印出的结果都是不按套路出牌。今天,我们就用三个框框搞懂它们,请看大屏幕。

2-1、总体介绍

看图说话。图中一共三个框框,分别是红色(R)、绿色(G)、蓝色(B)。

执行顺序:先执行红框,再执行蓝框,最后执行绿框(辅助记忆:RGB)。 这里我们要记住执行顺序,以及每个框是用来干什么的。

2-2、红框

红框是调用栈,所有的代码必须在这里执行,当在这里执行代码时,如果产生了异步任务,那么就按照一定类别把该异步任务放到蓝框或者绿框里。绝对不能阻塞红框里的其他代码执行。

2-3、蓝框

蓝框里放的一个个任务叫microTask,就是微任务的意思,当红框代码执行完毕后,红框就会从蓝框中取出一个任务并执行,在执行过程中如果产生了其他异步任务,那么继续放到蓝框或者绿框里。就这样,蓝框的一个个任务都被执行了。图中列举了几个属于microTask任务的API

2-4、绿框

绿框里放的一个个任务叫macroTask,就是宏任务的意思,当蓝框里的代码 执行完毕后,红框就会从绿框里取出一个任务并执行,在执行过程中如果产生了其他异步任务,那么继续放到蓝框或者绿框里。就这样,绿框的一个个任务都被执行了。图中列举了几个属于macroTask任务的API

3、哪些是macroTask,哪些是 microTask

知道了每个框的作用以及总体的执行顺序后,该说一下,哪些API属于microTask(蓝框),哪些API属于macroTask(绿框)。

microtask主要含:Promiseprocess.nextTickMutaionObserver

maicrotask主要含:setTimeoutsetIntervalsetImmediateI/O、UI交互事件

以上列出的这些API各自属于哪个任务必须要记住。

4、练习

说了那么多,来做几个练习吧。 先来个一年级的

setTimeout(() => {//放到了绿框里
    console.log(2)
}, 0);

new Promise(function (resolve) { resolve() }).then(function () {
    console.log(3)
})//放到了蓝框里

console.log(1)//默认在红框里,不动

以上代码的结果是1、3、2

解释一波吧:

  • 这段代码首先整体作为一个宏任务(macroTask)进入到红框。
  • 先遇到setTimeout,那么将其回调函数注册后分发到宏任务中,就是绿框里边。
  • 然后遇到了Promisethen函数分发微任务到微任务中,就是蓝框里。
  • 遇到console.log(),立即执行。
  • 到这里,整体代码作为第一个宏任务就执行结束了。接下来,该去蓝框看看了,发现有then,执行。
  • 然后再到绿框里拿出setTimeout的注册回调函数,执行
  • 结束。

再来一道复杂点儿的吧

console.log(1)

setTimeout(() => {
    console.log(2);
    process.nextTick(function () {
        console.log(3);
    })
}, 0);

process.nextTick(function () {
    console.log(4)
})

new Promise(function (resolve) {
    console.log(5);
    resolve()
}).then(function () {
    console.log(6)
})

以上代码执行结果为:1、5、4、6、2、3

分析过程留给大家吧,只要按照我们一开始说的,把所有的异步任务分门别类的放到对应的框框里,然后再按照RGB的顺序去执行,我相信,你能做对的。