宏任务 script,setTimeoout,setInterval,setlmmediate(node 独有),I/o,render渲染 微任务 process.nextTick(),promise 

 

1,执行timers阶段,执行setTimeOut()和setInterval到期的calback 2,I/O callbacks: 上一轮循环中少数callback/Io会被延迟到这一阶段执行 3,idle,prepare:队列的移动紧内部实现 4,poll:执行I/O,适当的条件下会阻塞这个阶段 5,check:执行setlmmediate的calback 6,close calback:执行close 事件的calback

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 1,1 例子 浏览器和node执行顺序的区别 setTimeout(()=>{     console.log('timer1')     Promise.resolve().then(function() {         console.log('promise1')     }) }, 0) setTimeout(()=>{     console.log('timer2')     Promise.resolve().then(function() {         console.log('promise2')     }) }, 0) 浏览器输出: time1 promise1 time2 promise2 Node输出: time1 time2 promise1 promise2
在这个例子中,Node的逻辑如下: 最初timer1和timer2就在timers阶段中。开始时首先进入timers阶段,执行timer1的回调函数,打印timer1,并将promise1.then回调放入microtask队列,同样的步骤执行timer2,打印timer2; 至此,timer阶段执行结束,event loop进入下一个阶段之前,执行microtask队列的所有任务,依次打印promise1、promise2。

 

例子2 setImmediate(() => {   console.log('timer1')   Promise.resolve().then(function () {     console.log('promise1')   }) }) setTimeout(() => {   console.log('timer2')   Promise.resolve().then(function () {     console.log('promise2')   }) }, 0) Node输出: timer1               timer2 promise1    或者     promise2 timer2               timer1 promise2             promise1

 

按理说setTimeout(fn,0)应该比setImmediate(fn)快,应该只有第二种结果,为什么会出现两种结果呢? 这是因为Node 做不到0毫秒,最少也需要1毫秒。实际执行的时候,进入事件循环以后,有可能到了1毫秒,也可能还没到1毫秒,取决于系统当时的状况。如果没到1毫秒,那么 timers 阶段就会跳过,进入 check 阶段,先执行setImmediate的回调函数。

 

 

另外,如果已经过了Timer阶段,那么setImmediate会比setTimeout更快,例如: const fs = require('fs'); fs.readFile('test.js', () => {   setTimeout(() => console.log(1));   setImmediate(() => console.log(2)); }); 上面代码会先进入 I/O callbacks 阶段,然后是 check 阶段,最后才是 timers 阶段。因此,setImmediate才会早于setTimeout执行。

 

3不同异步任务执行的快慢 setTimeout(() => console.log(1)); setImmediate(() => console.log(2)); Promise.resolve().then(() => console.log(3)); process.nextTick(() => console.log(4)); 输出结果:4 3 1 2或者4 3 2 1 因为我们上文说过microTask会优于macroTask运行,所以先输出下面两个,而在Node中process.nextTick比Promise更加优先[3],所以4在3前。而根据我们之前所说的Node没有绝对意义上的0ms,所以1,2的顺序不固定。

 

4MicroTask队列与MacroTask队列    setTimeout(function () {        console.log(1);    },0);    console.log(2);    process.nextTick(() => {        console.log(3);    });    new Promise(function (resolve, rejected) {        console.log(4);        resolve()    }).then(res=>{        console.log(5);    })    setImmediate(function () {        console.log(6)    })    console.log('end'); Node输出: 2 4 end 3 5 1 6 这个例子来源于《JavaScript中的执行机制》。Promise的代码是同步代码,then和catch才是异步的,所以4要同步输出,然后Promise的then位于microTask中,优于其他位于macroTask队列中的任务,所以5会优于1,6输出,而Timer优于Check阶段,所以1,6。
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄