async/await是什么
async是Generator的语法糖
基本上async
替代Generator函数声明所需的*
,而await
替代yeild
,而且在Genenrator中执行另外一个Genenrator时,yield需要加各*
,而await就不用加了。
总的说,async 用于申明一个 function 是异步的,而 await 用于等待一个异步方法执行完成。
async相对于Genertator的优点是它可以自动执行了,而不是需要一步步的next操作。实质上是async包含了一个自动执行函数。
Generator实质上多被应用在异步操作中,async/await显然更语义化。
async/await干什么
async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数。当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。
async function testAsync() {
return "hello async";
}
const result = testAsync();
console.log(result);//Promise { 'hello async' }
在上述例子可以看到,async的结果是一个promise对象,成功执行后它包含了resolve的信息。
那既然async跟promise有了关联,肯定也有它自己的优势,否则异步操作直接使用promise不就得了?
async的优势在于处理then链。
我们知道,await/yield就好比一个个关卡,直到执行ok才会开放下一步的通道,实质上then链也是一样的,直到上一步执行完毕有了结果,才会执行then函数。await和then本质上都依赖于上一步的结果。
使用await简化了异步函数的结构,再也不用写无穷无尽的then链,而是一步步的await了。
以下是对比:
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n + 200), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(n) {
console.log(`step2 with ${n}`);
return takeLongTime(n);
}
function step3(n) {
console.log(`step3 with ${n}`);
return takeLongTime(n);
}
function doIt() {
console.time("doIt");
const time1 = 300;
step1(time1)
.then(time2 => step2(time2))
.then(time3 => step3(time3))
.then(result => {
console.log(`result is ${result}`);
console.timeEnd("doIt");
});
}
doIt();
如果使用async:
async function doIt() {
console.time("doIt");
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time2);
const result = await step3(time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
doIt();
显然函数的层级关系更加明显。
上述例子是有关一个先后顺序异步的,如果我们需要并行的操作呢?
promise的all方法可以解决,我们将每一个await的结果存进一个数组里面。另外也可以使用for...of方法,不要忘记Generator是内置了遍历接口的。
在之前的Generator的小结里面有提到它可以抛出错误,那么我们可以结合一下,promise虽然有catch方法,但是链式结构显然不太简洁,我们可以利用try...catch代码块。
网友评论