event_loop中不一样异步操做的执行顺序

关于js的单线程、怎么建立一个异步任务都是老生常谈的话题了,咱们今天就总结一下js不一样的异步操做到底执行顺序如何。node

首先咱们要明白js两种任务类型,一个是macrotask(宏任务),一个是 microtask(微任务)。一个宏任务就是一个事件循环,一个宏任务执行完毕后js就会执行下一个宏任务,而微任务就是在两个宏任务执行中间执行。
咱们先给js中异步常见的异步操做来根据不一样任务类型进行分类ajax

宏任务promise

  • script(同步代码)
  • setTimeout
  • setInterval
  • setImmediate
  • I/O(ajax请求)异步

微任务函数

  • promise

    node中的process.nextTick是将任务放到当前宏任务的队尾执行,比较特殊,也算是一个特殊的微任务。oop

console.log(1);
setTimeout(()=>console.log(2), 1)
setTimeout(()=> console.log(3), 0)
Promise.resolve().then(()=> console.log(4));
setImmediate(()=> console.log(5))
process.nextTick(()=> console.log(6))
console.log(7);

因此咱们能够来测试下上面这段代码的执行顺序,首先确定输出的是 1 7 由于他们两个是属于第一个宏任务中的代码,接下来是 6 当前宏任务结束后process.nextTick 执行。而在下一个宏任务执行以前,微任务promise会指向,因此下来是 4。同时咱们要知道setTimeout的时间最小值是1因此 1 和 0 实际上是同样的,2必定会在3以前执行。可是setImmediate和setTimeout(, 0)执行顺序其实不肯定的,当咱们将这段代码直接在node中执行,输出的是1764235,也就是说setImmediate后执行。可是咱们将这段代码放到一个setTimeout中执行,输出的是1764523。测试

咱们知道 setTimeout 的回调函数在 timer 阶段执行,setImmediate 的回调函数在 check 阶段执行,event loop 的开始会先检查 timer 阶段,可是在开始以前到 timer 阶段会消耗必定时间,因此就会出现两种状况:

timer 前的准备时间超过 1ms,知足 loop->time >= 1,则执行 timer 阶段(setTimeout)的回调函数
timer 前的准备时间小于 1ms,则先执行 check 阶段(setImmediate)的回调函数,下一次 event loop 执行 timer 阶段(setTimeout)的回调函数

这是对网上对这个现象的解释。线程

相关文章
相关标签/搜索