一个例子来说明setTimeout、Promise、Async/Await的执行顺序

JavaScript的事件循环(Event Loop)

同步和异步任务分别进入不同的执行"场所",同步的进入主线程(执行栈),异步的进入Event Table并注册函数。当指定的事情完成时,Event Table会将这个函数移入Event Queue。

主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。上述过程会不断重复,也就是常说的Event Loop(事件循环)。

这里异步任务的Event Queue分两种情况的,即宏任务(macrotask)微任务(microtask),当主线程任务完成为空去Event Quenu读取函数的时候,是先读取的微任务,当微任务执行完毕之后,才会继续执行宏任务。

综上事件循环为:同步>异步   微任务>宏任务

那么微任务和宏任务都有什么呢,简单总结下就是:

微任务:Promiseprocess.nextTick

宏任务:整体代码scriptsetTimeoutsetInterval

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"。

 

 

 

posted on 2021-03-26 15:57  程序员阿田  阅读(392)  评论(2)    收藏  举报

导航