美文网首页
async await

async await

作者: 灯不梨喵 | 来源:发表于2018-01-03 17:10 被阅读0次

    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代码块。

    相关文章

      网友评论

          本文标题:async await

          本文链接:https://www.haomeiwen.com/subject/ciapgxtx.html