经典执行顺序题
JS是单线程:同一时间只能做一件事情。
但是有些任务是耗时的,会阻塞代码的执行
因此,将代码分为同步代码和异步代码
同步代码立刻放进JS引起执行,原地等待结果。
异步代码放入宿主环境,不阻塞主线程,主线程继续执行代码,异步执行的结果将在将来执行
时间一到,宿主环境将回调函数推送到任务队列,任务队列推送到执行栈
整个是一个循环的过程,将会不断检测执行站和任务队列。
顺序: 同步代码,微任务入栈,宏任务入栈
原则:先进先出,将所有微任务入栈,执行完后再检查一遍有没有微任务,清空微任务后再执行宏任务
console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
new Promise((resolve) => {
console.log('3');
resolve();
}).then(() => {
console.log('4');
});
console.log('5');
// 问:输出顺序是什么?
```
<details>
<summary>答案</summary>
```
1
3
5
4
2
解析:
console.log('1')- 同步代码setTimeout- 宏任务,放入宏任务队列new Promise- 构造函数同步执行,输出3.then()- 微任务,放入微任务队列console.log('5')- 同步代码- 微任务先执行:输出
4 - 宏任务后执行:输出
2
async/await 与 Promise 混合
await要阻塞等待其执行 await后面的代码算微任务
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(() => {
console.log('setTimeout');
}, 0);
async1();
new Promise(resolve => {
console.log('promise1');
resolve();
}).then(() => {
console.log('promise2');
});
console.log('script end');
// 问:输出顺序?
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
解析:
await async2()相当于Promise.resolve(async2()).then(() => console.log('async1 end'))await后面的代码被放入微任务队列