javascript在执行时,遇到异步执行的方法,不会等异步方法返回结果再继续向下执行,而是先将异步方法放到一个队列中,然后继续执行,最后主线程空闲时,再按照顺序执行队列里的异步方法,叫做事件轮回。队列又分为宏队列和微队列,将宏任务放在宏队列,微任务放在微队列,在执行时遵循先全局方法,后微任务,最后宏任务的顺序。
宏任务:setTimeout, setInterval, setImmediate, I/O, UI rendering.
微任务:process.nextTick, Promise.then, Object.observer, MutationObserver.
console.log('1->全局队列script');
setTimeout(() => {
console.log('2->timeout1');
new Promise(resolve=>{
console.log('3->timeout1-promise');
resolve()
}).then(()=>{
console.log('4-timeout1-then');
})
}, 2000);
new Promise(resolve=>{
console.log('5->promise1');
resolve()
}).then(()=>{
console.log('6->then=>1')
})
结果为:
1->全局队列script
5->promise1
6->then=>1
2->timeout1
3->timeout1-promise
4-timeout1-then
先执行1全局队列,将settimeout内的放到宏队列中,执行5全局队列,将then中的6放到微队列中,主程序空闲,执行微任务6,然后执行宏任务settimeout(先执行2,3,将4放入微任务中,2,3执行完后执行4)
setImmediate类似于setTimeout(()=>{},0),执行先后不同场景下不同,在文件I/O和网络I/O中,setImmediate会先于setTimeout,在其他一般情况下,setTimeout会先于setImmediate。
script(主程序代码)——>process.nextTick——>promise——>setTimeout——>setImmediate