前面我们说到了promise
,那么接下来我们应该更容易理解async/await
一些。
async:async
表示函数是一个异步函数,它的返回值是一个promise
,因此我们可以使用then方法来给它添加回调。
await:await会使async函数暂停执行,等待promise的结果出来,然后恢复async函数的执行并返回解析值。await
就是then
的一个语法糖,这样将resolve的值直接返回,使用起来就更加的方便。所以我们可以认为async/await的存在是为了简化使用多个promise时的同步行为。
对于promise
和async/await
,引用MDN官方的术语,promise类似于结构化回调。async/await更类似于组合生成器和promise
注意:需要注意的使await只能在async函数中使用,如果在外部使用,你可能会得到一个语法错误。
具体的我们可以像下面这样来使用它:
var resolveAfter2 = function (){
return new Promise(resolve=>{
setTimeout(()=>{
resolve('slow');
},2000);
});
};
var resolveAfter1 = function(){
return new Promise(resolve=>{
setTimeout(()=>{
resolve('fast');
},1000)
})
}
var sequentialStart = async function(){
const slow = await resolveAfter2();
console.log(slow);
const fast = await resolveAfter1();
console.log(fast);
}
sequentialStart(); //打印的顺序是slow,fast
//这说明一个问题,就是等第一个swait执行完成之后,才执行的第二个await,总共的时间花了3秒
但是我们来看下面这个列子
var concurrentStart = async function() {
console.log('==CONCURRENT START with await==');
const slow = resolveAfter2(); // starts timer immediately
const fast = resolveAfter1(); // starts timer immediately
// 1. Execution gets here almost instantly
console.log(await slow); // 2. this runs 2 seconds after 1.
console.log(await fast); // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
}
但是当两个计时器同时运行的时候,结果也是先打印出slow,然后再打印出fast,与上面的代码不同的是,这次结果是在两秒之内打印完成的,原因就在于这两个计时器是一起被await的。
再来看一个例子
var paralell = async function(){
await Promise.all([
(async()=>console.log(await resolveAfter2()))(),
(async()=>console.log(await resolveAfter1()))()
]);
}
结果是先输出fast,过了一秒之后输出了slow,总共用了两秒。所以当你希望并行等待多个任务的时候,你应该使用await promise.all([promise1,promise2]);
再来看一下没有使用async的例子,那么它的结果是多少呢?
var parallelPromise = function() {
console.log('==PARALLEL with Promise.then==');
resolveAfter2Seconds().then((message) => console.log(message));
resolveAfter1Second().then((message) => console.log(message));
}
paralell();
应该也是先输出fast,然后输出slow,时间是总共用来两秒