美文网首页
Node 的事件循环

Node 的事件循环

作者: 涅槃快乐是金 | 来源:发表于2022-03-12 22:51 被阅读0次

node的事件循环比浏览器复杂很多。由6个宏任务队列+6个微任务队列组成。

宏任务按照优先级从高到低依次是:

其执行规律是:在一个宏任务队列全部执行完毕后,去清空一次微任务队列,然后到下一个等级的宏任务队列,以此往复。一个宏任务队列搭配一个微任务队列。

六个等级的宏任务全部执行完成,才是一轮循环。

其中需要关注的是:Timers、Poll、Check阶段,因为我们所写的代码大多属于这三个阶段。

    1. Timers:定时器setTimeout/setInterval;
    1. Poll :获取新的 I/O 事件, 例如操作读取文件等;
    1. Check:setImmediate回调函数在这里执行;

除此之外,node端微任务也有优先级先后:

    1. process.nextTick;
    1. promise.then 等;

清空微任务队列时,会先执行process.nextTick,然后才是微任务队列中的其他。

下面这段代码可以佐证浏览器和node的差异:

console.log('Script开始')
setTimeout(() => {
  console.log('第一个回调函数,宏任务1')
  Promise.resolve().then(function() {
    console.log('第四个回调函数,微任务2')
  })
}, 0)
setTimeout(() => {
  console.log('第二个回调函数,宏任务2')
  Promise.resolve().then(function() {
    console.log('第五个回调函数,微任务3')
  })
}, 0)
Promise.resolve().then(function() {
  console.log('第三个回调函数,微任务1')
})
console.log('Script结束')
node端:
Script开始
Script结束
第三个回调函数,微任务1
第一个回调函数,宏任务1
第二个回调函数,宏任务2
第四个回调函数,微任务2
第五个回调函数,微任务3

浏览器
Script开始
Script结束
第三个回调函数,微任务1
第一个回调函数,宏任务1
第四个回调函数,微任务2
第二个回调函数,宏任务2
第五个回调函数,微任务3

可以看出,在node端要等当前等级的所有宏任务完成,才能轮到微任务:第四个回调函数,微任务2在两个setTimeout完成后才打印。

因为浏览器执行时是一个宏任务+一个微任务队列,而node是一整个宏任务队列+一个微任务队列。

node11.x 前后版本差异

node11.x 之前,其事件循环的规则就如上文所述:先取出完一整个宏任务队列中全部任务,然后执行一个微任务队列。

但在11.x 之后,node端的事件循环变得和浏览器类似:先执行一个宏任务,然后是一个微任务队列。但依然保留了宏任务队列和微任务队列的优先级。

可以用下面的Demo佐证:

console.log('Script开始')
setTimeout(() => {
  console.log('宏任务1(setTimeout)')
  Promise.resolve().then(() => {
    console.log('微任务promise2')
  })
}, 0)
setImmediate(() => {
  console.log('宏任务2')
})
setTimeout(() => {
  console.log('宏任务3(setTimeout)')
}, 0)
console.log('Script结束')
Promise.resolve().then(() => {
  console.log('微任务promise1')
})
process.nextTick(() => {
  console.log('微任务nextTick')
})

在 node11.x 之前运行:

Script开始
Script结束
微任务nextTick
微任务promise1
宏任务1(setTimeout)
宏任务3(setTimeout)
微任务promise2
宏任务2(setImmediate)

在 node11.x 之后运行:

Script开始
Script结束
微任务nextTick
微任务promise1
宏任务1(setTimeout)
微任务promise2
宏任务3(setTimeout)
宏任务2(setImmediate)

可以发现,在不同的node环境下:

  1. 微任务队列中process.nextTick都有更高优先级,即使它后进入微任务队列,也会先打印微任务nextTick微任务promise1;
  2. 宏任务setTimeout比setImmediate优先级更高,宏任务2(setImmediate)是三个宏任务中最后打印的;
  3. 在node11.x之前,微任务队列要等当前优先级的所有宏任务先执行完,在两个setTimeout之后才打印微任务promise2;在node11.x之后,微任务队列只用等当前这一个宏任务先执行完。

相关文章

  • node 事件

    1、事件 1.1普通事件的使用 1.2、Node.js 的事件循环机制解析 1)Node 由事件循环开始,到事件循...

  • node 事件循环

    概念 -单线程、单进程,结合V8的异步回调接口,处理大量并发-API支持回调函数-事件机制采用设计模式中观察者模式...

  • Node事件循环

    Node.js 事件循环机制 Node.js 采用事件驱动和异步 I/O 的方式,实现了一个单线程、高并发的 Ja...

  • node事件循环

    事件循环 事件循环是一个典型的生产者/消费者模式,网络请求,异步IO源源不断的产生提供不同类型的事件到观察者哪里,...

  • node事件循环

    浏览器事件循环见:https://www.jianshu.com/p/64bbefbe5ae5[https://w...

  • Node事件循环

    Node架构图 事件循环核心 核心模块就是LIBUV 在linux上,libuv是对epoll的封装; 在wind...

  • Node事件循环

    官网事件循环:https://nodejs.org/zh-cn/docs/guides/event-loop-ti...

  • 学习 nodejs I /O 交互

    1 事件循环 Node的执行模型实际上是事件循环。在进程启动时,Node会创建一个无限循环,每一次执行循环体的过程...

  • node.js的事件循环

    在node中,事件循环表现出的状态与浏览器中大致相同。不同的是node中有一套自己的模型。node中事件循环的实现...

  • Node的事件循环

    1.同步任务与异步任务(1)同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行下一个任务;(2)...

网友评论

      本文标题:Node 的事件循环

      本文链接:https://www.haomeiwen.com/subject/vmgldrtx.html