js的event loop

97 阅读3分钟

###前言:js的eventLoop分宏任务和微任务

浏览器端eventLoop

  • 浏览器端在一个事件循环内,先执行同步任务
  • 再执行微任务队列中的微任务,队列中所有微任务执行完后
  • 最后再执行宏任务队列中的宏任务
  • 优先执行宏任务中的同步代码
  • 若宏任务中存在微任务,则将微任务push到微任务队列
  • 遇到宏任务,则放到宏任务队列。
  • 同步代码执行完后再取出微任务队列中的所有微任务执行
  • 再执行宏任务,进入到下一个事件循环

旧版nodejs的event loop

  • 存在一个微任务队列
  • 微任务队列存放Promise.then方法和process.nextTick方法。
  • 存在六个阶段的宏任务队列
  • timer阶段 (处理定时器相关任务,定时有liubv库中的延时队列维护)
  • idle阶段 (nodejs内部使用)
  • IO Callback阶段 (执行io的回调)
  • poll阶段(由libuv库调用操作系统内核的io机制实现io多路复用)https://juejin.cn/post/7040310112707149855
  • check阶段 (执行setimmediate回调)
  • close阶段 (执行socket链接关闭等事件)
  • 执行流程
  • 先执行eventLoop中的同步代码
  • 遇到微任务方微任务队列
  • 遇到宏任务放对应阶段的宏任务队列
  • 同步代码执行完后,执行所有的微任务队列代码。(微任务队列中process.nextTick,优先与promise.then执行)。队列中的微任务全都执行完。
  • 微任务队列全部执行完后,在执行下个阶段的宏任务队列
  • 若一个阶段中的宏任务有多个,就会将这个阶段中的所有宏任务执行完后再执行微任务队列总的任务。(

注意:旧版nodejs这里是和浏览器不同的。

  • nodejs: 需要等当前阶段的所有宏任务执行完后在执行微任务
  • 浏览器:执行完一个宏任务就去执行所有的微任务队列,不用等到所有的宏任务执行完

新版nodejs的eventLoop

eventLoop的队列结构和旧版nodejs是一模一样的,也是一个微任务队列,六个阶段的宏任务队列。

  • 执行流程
  • 先执行eventLoop中的同步代码
  • 遇到微任务方微任务队列
  • 遇到宏任务放对应阶段的宏任务队列
  • 同步代码执行完后,执行所有的微任务队列代码。(微任务队列中process.nextTick,优先与promise.then执行)。队列中的微任务全都执行完。
  • 微任务队列全部执行完后,在执行下个阶段的宏任务队列
  • 若一个阶段中的宏任务有多个,则执行完一个宏任务就会取出微任务队列中所有的微任务进行全部执行。再进行当前宏任务阶段的下一个宏任务。

注意:这里是和旧版nodejs不一样的。

  • 旧版nodejs: 需要等当前阶段的所有宏任务执行完后再执行微任务
  • 新版nodejs:执行完一个宏任务就去执行所有的微任务队列,不用等到所有的宏任务执行完。(新版本的nodejs这里的执行机制又和浏览器保持一致了)