在JS的event loop
中,有两种任务队列microtasks
和macrotasks
promise
microtasksoop
macrotaskscode
在一个事件循环event loop的周期中,一个task应该从macrotask队列开始执行。当这个macrotask结束后,全部的microtasks将在同一个cycle中执行。
且在microtasks执行时还能够加入更多的microtask,而后一个一个的执行,直到microtask队列清空。server
console.log('start') const interval = setInterval(() => { console.log('setInterval') }, 0) setTimeout(() => { console.log('setTimeout 1') Promise.resolve() .then(() => { console.log('promise 3') }) .then(() => { console.log('promise 4') }) .then(() => { setTimeout(() => { console.log('setTimeout 2') Promise.resolve() .then(() => { console.log('promise 5') }) .then(() => { console.log('promise 6') }) .then(() => { clearInterval(interval) }) }, 0) }) }, 0) Promise.resolve() .then(() => { console.log('promise 1') }) .then(() => { console.log('promise 2') })
event loop1:
macrotasks: [主程序代码]
microtasks: []队列
执行macrotasks队列,也即执行主程序代码,收集macro或micro的tasks
输出: 'start'
收集的macrotasks(下次循环的): [setInterval, setTimeout]
收集的microtasks(当前循环的): [Promise]事件
macrotasks队列执行完毕,这时候microtasks: [Promise]不为空,执行microtasks队列
输出: 'promise1'
输出 : 'promise2'
这时候microtasks为空io
下次循环开始以前的队列状态
macrotasks: [setInterval, setTimeout]
microtasks: []console
event loop2:
执行macrotasks队列
执行setInterval
输出:'setInterval',且收集setInterval到下次循环的macrotasks中
执行setTimeout
输出:'setTimeout 1',且收集Promise到当前循环的microtasks: [Promise]event
因为当前循环的microtasks不为空,执行队列中的任务Promise
输出:'promise3'
输出: 'promise4'
收集setTimeout到下次循环的macrotasks中
这时候microtasks为空class
下次循环开始以前的队列状态
macrotasks: [setInterval, setTimeout]
microtasks: []
event loop3:
执行macrotasks队列
执行setInterval
输出: 'setInterval',且收集setInterval到下次循环的macrotasks: [setInterval]中
执行setTimeout
输出: 'setTimeout2',且收集Promise到当前的microtasks: [Promise]
因为当前循环的microtasks不为空,执行队列中的任务Promise
输出: 'promise5'
输出: 'promise6'
清除定时器clearInterval,因此下次循环的macrotasks的setInterval被清除
下次循环开始以前的队列状态
macrotasks: []
microtasks: []
event loop4:
因为macrotasks为空,和microtasks为空,程序处于等待状态。
上面程序总的输出结果是
// event loop1 start promise 1 promise 2 // event loop2 setInterval setTimeout 1 promise 3 promise 4 // event loop3 setInterval setTimeout 2 promise 5 promise 6