一个例子来说明setTimeout、Promise、Async/Await的执行顺序
JavaScript的事件循环(Event Loop)
同步和异步任务分别进入不同的执行"场所",同步的进入主线程(执行栈),异步的进入Event Table并注册函数。当指定的事情完成时,Event Table会将这个函数移入Event Queue。
主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。上述过程会不断重复,也就是常说的Event Loop(事件循环)。
这里异步任务的Event Queue分两种情况的,即宏任务(macrotask)和微任务(microtask),当主线程任务完成为空去Event Quenu读取函数的时候,是先读取的微任务,当微任务执行完毕之后,才会继续执行宏任务。
综上事件循环为:同步>异步 微任务>宏任务
那么微任务和宏任务都有什么呢,简单总结下就是:
微任务:Promise,process.nextTick
宏任务:整体代码script,setTimeout,setInterval
async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2() { console.log('async2'); } console.log('start'); setTimeout(() => { console.log('setTimeout');
}, 0); async1(); new Promise(resolve => { console.log('promise1'); resolve(); }).then(() => { console.log('promise2'); }) var arr = []; for (let index = 0; index < 10000000; index++) { arr.push(index); } console.log(arr); console.log('end');


分析:
1、主函数打印"start"。
2、执行setTimeout,将setTimeout回调函数放入异步宏任务队列。
3、调用async1,依次打印"async1 start"、"async2",将await后面的回调函数放到异步微任务队列。
4、执行new Promise,输出"promise1",将then里面的回调函数放入异步微任务队列。
5、执行耗时长的循环语句并打印"arr",并且输出"end",这时候主栈执行完毕为空。
6、将异步微任务队列里的函数按照"先进先出"的顺序依次执行,输出"async1 end","promise2"。
7、将异步宏任务队列里的函数按照"先进先出"的顺序依次执行,输出"setTimeOut"。

浙公网安备 33010602011771号