async/await
async 会返回 promise,await 等待一个 promise resolve 的值,如果等待非 promise,会返回该值本身,相当于 await Promise.resolve(xxx)
光看起来没什么难度,我们来看一下大厂常考的事件循环的面试题
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2 start');
return new Promise((resolve, reject) => {
resolve();
console.log('async2 promise');
})
}
async1();
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
}).then(function () {
console.log('promise3');
}).then(()=>{
console.log('promise4')
})
结果如下
对于此类问题,我的解决方法是将其改写为 promise 的形式,那么我们开始吧
对于第一个 async 函数
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
我们知道 await 在等待 async2 的结果 resolve 之后,再去将第四行代码当作 then 的回调,那么可得出以下结论
function async1(){
console.log('async1 start')
return new Promise((resolve,reject)=>{
async2().then(()=>{
resolve()
}).then(()=>{
console.log('async1 end');
})
})
}
对于第二个 async 函数
async function async2() {
console.log('async2 start');
return new Promise((resolve, reject) => {
resolve();
console.log('async2 promise');
})
}
我们看到,函数主动返回了一个 promise,那么最终返回的 promise 由你手动返回的 promise 来决定,所以可得出以下结论
function async2(){
console.log('async2 start')
return new Promise((resolve,reject)=>{
new Promise((resolve2,reject2)=>{
resolve2()
console.log('async2 promise')
}).then(()=>{
resolve()
})
})
}
等待手动返回的 promise resolve 后,返回的 promise 才会 resolve
也就是说,外界 await 等待的是 async 自动包装的 promise 的 resolve,而不是我们手动返回的 promise,所以我的用词是 ‘手动返回的 promise’ 和 ‘返回的 promise’,要区分清楚
然后我们试验一下改写后的形式,是否和原来一样
function async1(){
console.log('async1 start');
return new Promise((resolve,reject)=>{
async2().then(()=>{
resolve()
}).then(()=>{
console.log('async1 end');
})
})
}
function async2(){
console.log('async2 start');
return new Promise((resolve,reject)=>{
new Promise((resolve2,reject2)=>{
resolve2()
console.log('async2 promise');
}).then(()=>{
resolve()
})
})
}
async1();
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
}).then(function () {
console.log('promise3');
}).then(()=>{
console.log('promise4')
})
我们掌握了改写技巧后,就能轻易地判断事件循环啦
还有几种其他的情况,比如
async function async1(){
console.log('async1')
}
// 等价于
function async1(){
console.log('async1')
return Promise.resolve(undefined)
}
async function async1(){
await console.log('async1')
}
// 等价于
function async1(){
console.log('async1')
return Promise.resolve(undefined)
}
核心就是每个函数 resolve 的时机,当然要对 promise 有一定的理解才行,建议多手写 promise 来加深理解