本文摘自边城的理解JavaScript的async/await一文以及git上Mavericker-1996关于async/await的一些见解
主要需要理解javascript中同步任务、异步任务、宏任务和任务。
宏任务(macro task)主要包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChange、setImmediate。
微任务(micro task)主要包含:Promise.then、MutainObserver、process.nextTick。
关于async/await关键的一点就是:
如果await后面等待的不是一个Promise对象,那么await表达式的运算结果就是它等待的东西
如果await后面等待的是一个Promise对象,await就忙起来了,它会阻塞后面的代码,等待Promise对象resolve,然后得到resolve的值,作为await表达式的运算结果
但是async函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个Promise对象的中异步执行。这就是await必须用在async函数中的原因
你可以通过以下几题来来看看你对async/await知多少,或通过以下几题来加深对async/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(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
题二:
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
//async2做出如下更改:
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise3');
resolve();
}).then(function() {
console.log('promise4');
});
console.log('script end');
题三:
async function async1() {
console.log('async1 start');
await async2();
//更改如下:
setTimeout(function() {
console.log('setTimeout1')
},0)
}
async function async2() {
//更改如下:
setTimeout(function() {
console.log('setTimeout2')
},0)
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout3');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
题四:
async function a1 () {
console.log('a1 start')
await a2()
console.log('a1 end')
}
async function a2 () {
console.log('a2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
console.log('promise1')
});
a1()
let promise2 = new Promise((resolve) => {
resolve('promise2.then')
console.log('promise2')
});
promise2.then((res) => {
console.log(res)
Promise.resolve().then(() => {
console.log('promise3')
})
})
console.log('script end')
题五:
async function async1() {
console.log('async1 start')
await async2().then(res=>{console.log(res)});
console.log('async1 end')
}
async function async2() {
return new Promise((res,rej)=>{
console.log('promise1')
res('promise1 res')
}).then((res)=>{
console.log(res)
console.log('promise2')
return 'promise2 res'
})
}
console.log('script start')
setTimeout(()=>{
console.log("setTimeout")
}, 0)
async1()
new Promise((res,rej)=>{
console.log('promise3')
res()
}).then(()=>{
console.log('promise4')
})
console.log('script end')