这是我参与「第四届青训营 」笔记创作活动的第1天
事件循环
为什么会有事件循环
- JavaScript 是一门单线程的语言,它的异步和多线程的实现是通过 Event Loop 事件循环机制来实现的。
事件循环解释
-
一个线程中,事件循环是唯一的,但是任务队列可以拥有多个。任务队列又分为macro-task(宏任务)与micro-task(微任务),在最新标准中,它们被分别称为task与jobs。
-
执行宏任务,然后执行该宏任务产生的微任务,若微任务在执行过程中产生了新的微任务,则继续执行微任务,微任务执行完毕后,再回到宏任务中进行下一轮循环\
-
resolve() reject() 之后 推进入到微任务队列的。
-
定时器到点后 推入到宏任务队列
任务队列
宏任务
-
script(整体代码)
-
setTimeout
-
setInterval
-
setImmediate
-
I/O
-
UI render
微任务
- promise.then/cath /finally, 这些回调
- await后面的函数执行完毕时,await会产生一个微任务(Promise.then是微任务)。
await 右边是什么会影响 await 下面代码输出顺序
-
await 右边是值,则下面的代码在执行完await后作为 微任务入队。直接把await后面的代码注册为一个微任务,可以简单理解为promise.then(await下面的代码)
-
await 右边是promise结果,则退出当前函数上下文,去执行别的代码,最后入队await下面的代码到微任务队列,await 后面的代码会在本轮循环的最后被执行
node中的事件循环
- node11 版本一旦执行一个阶段里的一个宏任务(setTimeout,setInterval和setImmediate)就立刻执行对应的微任务队列。
-
每个框被称为事件循环机制的一个阶段,每个阶段都有一个 FIFO 队列来执行回调。虽然每个阶段都是特殊的,但通常情况下,当事件循环进入给定的阶段时,它将执行特定于该阶段的任何操作,然后执行该阶段队列中的回调,直到队列用尽或最大回调数已执行。当该队列已用尽或达到回调限制,事件循环将移动到下一阶段。
-
输入数据阶段(incoming data)->轮询阶段(poll)->检查阶段(check)->关闭事件回调阶段(close callback)->定时器检测阶段(timers)->I/O事件回调阶段(I/O callbacks)->闲置阶段(idle, prepare)->轮询阶段...