Appearance
全局配置
Appearance
async function async1() {
console.log(1);
await async2();
console.log(2);
}
async function async2() {
console.log(3);
}
async1();
setTimeout(() => console.log(4), 0);
new Promise(resolve => {
resolve();
console.log(5);
}).then(() => {
console.log(6);
Promise.resolve().then(()=>{
console.log(7);
})
});
console.log(8);
// 正确答案:13582674
TIP
每一个当下,正在被执行的JS代码是放在JS的主线程(我们叫JS Stack)的。同步的代码会按照代码顺序依次放入JS Stack,然后按照放入的顺序依次执行。
异步的代码会被放入Macrotask或者Microtask,promise属于Microrask。这篇文章,我们先忽略Macrotask。
异步的代码一定是要等到同步的代码执行完了才执行。也就是说,直到JS Stack为空,Microtask里面的代码才会被提到JS Stack,然后被执行。
new Promise()和.then()方法属于同步代码。
.then()时只是注册callback方法,并不会把callback方法加入Microtask
.then(resolveCallback, rejectCallback)里面的resolveCallback, rejectCallback的执行属于异步代码,会在执行了resolve之后被放入Microtask。
resolve()被调用会起到2点作用
(1). Promise由pending状态变为resolved
(2). 遍历这个promise上所注册的所有的resolveCallback方法,依次加入Microtask。
一句话解释:await会阻塞后面的任务,指的是下一行代码,await同行代码是会立即执行的。
async function async1() {
console.log(1);
await async2();
console.log(2);
}
async function async2() {
console.log(3);
}
相当于:
async function async1() {
console.log(1);
new Promise((resolve) => {
console.log(3);
resolve();
}).then(() => {
console.log(2);
})
}
await的下一行代码开始才是异步代码。await修饰的函数(同行)仍然是同步的。但需要考虑函数的调用栈,执行到调用栈内部遇到真正第一个微任务才将改微任务如队。
await是Promise.then的语法糖,有await则存在微任务回调,无await则不存在,即使外层使用了async包裹,那也只是返回符合promise格式的包装,并不存在微任务,如下面async3中,仅有同步代码,并没有微任务。但是调用async3的async2的await后有代码,存在微任务。是此段代码的第一个微任务。
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
await async3();
console.log('async2');
}
async function async3() {
console.log('async3');
}
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');
结果是:
script start
async1 start
async3
promise1
script end
async2
promise2
async1 end
undefined
setTimeout
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
await async3();
console.log('async2');
}
async function async3() {
console.log('async3');
}
相当于
async function async1() {
console.log('async1 start');
new Promise(resolve => {
new Promise(resolve2 => {
console.log('async3');
resolve2();
}).then(() => {
console.log('async2');
});
resolve();
}).then(() => {
console.log('async1 end');
});
}
遇到then,就将其加入微任务队列,因此按照函数调用栈顺序,console.log('async2')
先于console.log('async1 end')
加入微任务队列。