0%

setimeout async promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log( 'async2');
}
console.log("script start");
setTimeout(function () {
console.log("settimeout");
},0);
async1();
new Promise(function (resolve) {
console.log("promise1");
resolve();
}).then(function () {
console.log("promise2");
});
console.log('script end');
1
2
3
4
5
6
7
8
script start
async1 start
async2
promise1
script end
async1 end
promise2
settimeout

解这个题目需要引入三个概念

执行栈

当一个脚本第一次执行的时候,js引擎会解析这段代码,并将其中的同步代码按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。。这个过程反复进行,直到执行栈中的代码全部执行完毕。

宏任务(task)

浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->…)
鼠标点击会触发一个事件回调,需要执行一个宏任务,然后解析HTMl。

以下事件属于宏任务:

  • setInterval()
  • setTimeout()

微任务(Microtasks )

微任务通常来说就是需要在当前 task 执行结束后立即执行的任务,比如对一系列动作做出反馈,或或者是需要异步的执行任务而又不需要分配一个新的 task,这样便可以减小一点性能的开销。只要执行栈中没有其他的js代码正在执行且每个宏任务执行完,微任务队列会立即执行。如果在微任务执行期间微任务队列加入了新的微任务,会将新的微任务加入队列尾部,之后也会被执行。

以下事件属于微任务:

  • new Promise()
  • new MutaionObserver()

然后我们再来看题目、该题目的执行栈、宏任务队列、微任务队列如下

化身状态机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
async function async1() {         // 1、声明函数体
console.log("async1 start"); // 6、进入执行栈并直接执行
await async2(); // 7、标记执行完毕async2后让出当前线程(简单理解的话可以吧await之下的内容当成promise.then之后的内容)
console.log("async1 end"); // 9、压入微任务队列 // 13、从微事件队列中取出进入执行栈执行
}
async function async2() { // 2、声明函数体
console.log( 'async2'); // 8、进入执行栈并直接执行
}
console.log("script start"); // 3、进入执行栈并直接执行
setTimeout(function () { // 4、压入宏任务队列
console.log("settimeout"); // 15、从宏事件队列中取出进入执行栈执行
},0);
async1(); // 5、执行async1函数
new Promise(function (resolve) { //
console.log("promise1"); // 10、进入执行栈并直接执行
resolve();
}).then(function () { // 11、压入微任务队列
console.log("promise2"); // 14、从微事件队列中取出进入执行栈执行
});
console.log('script end'); // 12、进入执行栈并直接执行

参考

https://segmentfault.com/a/1190000014940904

https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly

https://www.cnblogs.com/cangqinglang/p/8967268.html

https://blog.csdn.net/baidu_33295233/article/details/79335127

http://www.cnblogs.com/dong-xu/p/7000163.html

https://zhuanlan.zhihu.com/p/55511602?utm_source=com.tencent.qqlite&utm_medium=social