async/await的理解

遇到个五连回调的代码,真的是地狱级拷打,用async await进行了一波改写,顿时神清气爽,总结一下。
顾名思义,async是异步的简写,awaitasync await的简写。所以async就是用于声明一个function是异步的,而await就是用来等待这个异步方法执行完成的。另外,规定await只能在async中使用。

async作用及工作原理

先看下async是怎么处理返回值的

    async function testAsync() {
    return "hello world";
    }

    const result = testAsync();
    console.log(result);// Promise {'hello world'}

可见,async返回一个Promise对象。如果在async函数中直接return一个值,那么async会把这个值通过Promise.resolve()封装成Promise对象。Promise的特点——无等待,所以在没有使用await的情况下,async会立即执行,不会阻塞后面的代码。

await在等谁呢?

原以为,await在等待async的函数完成,等async的讯息。看了文档后,await等待的其实是一个表达式,这个表达式的计算结果是Promise对象或者其它值。
await不仅仅用于等Promise对象,它可以等任意表达式的结果,所以await是可以接普通函数的。

    function getValue() {
        return 123;
    }

    async function testAsync() {
        return Promise.resolve("hello world");
    }

    async function test() {
        const v1 = await getValue();
        const v2 = await testAsync();
        console.log(v1, v2);// 123 hello world
    }

    test();

await等到结果之后

返回Promise对象的处理结果,如果等待的不是Promise对象,则返回值本身。
await会在暂停async函数,等待Promise处理完成。
如果Promise正常处理,则回调的resolve函数参数作为await的值,继续执行async函数。
如果Promise处理异常,await会把Promise的异常原因抛出。

为啥要使用async/await

反正都是处理Promise对象,为啥不直接用.then()呢?用setTimeout模拟耗时的异步操作。

    function mockApi() {
        return new Promise((resolve) => {
            setTimeout(() => resolve("hello world"), 1000);
        });
    }

    // then写法
    mockApi().then(v => {
        console.log("then", v);
    })

    // async/await写法
    async function test() {
        const v = await mockApi();
        console.log(v);
    }

test();

async/await反而要多写一点代码,繁重的工作雪上加霜了。😂😂😂😂😂
不要着急,脱裤子肯定不是为了...
单一的Promise链并不能发现async/await的妙用😏,当遇到多个Promise组成的then链时,你会发现async/await就是救世主。
试试看,一个业务处理分成多个步骤,每一步都是异步 的,而且每一步都依赖前一步的结果。
setTimeout受累一下😙😙😙

/**
 * 传入参数value,表示这个函数执行的时间
 * 执行结果增加1000,用于下一步
 * @param {*} value 时间
 * @returns 时间+1000ms
 */
    function mockApi(value) {
    return new Promise((resolve) => {
        setTimeout(() => resolve(value + 1000), value);
    });
    }

    function step1(value) {
    console.log(`step1 with ${value}`);
    return mockApi(value);
    }

    function step2(value) {
    console.log(`step2 with ${value}`);
    return mockApi(value);
    }

    function step3(value) {
    console.log(`step3 with ${value}`);
    return mockApi(value);
    }

    // then写法

    function testThen() {
    console.time("testThen");
    const time1 = 300;
    step1(time1).then((time2) => {
        step2(time2).then((time3) => {
        step3(time3).then((result) => {
            console.log(`result is ${result}`); // 我已经晕了😵😵😵😵
            console.timeEnd("testThen");
        });
        });
    });
    }

    testThen();
    // step1 with 300
    // step2 with 1300
    // step3 with 2300
    // result is 3300
    // testThen: 3921.948ms

    // async/await写法
    async function testAsync() {
        console.time("testAsync");
        const time1 = 300;
        const time2 = await step1(time1);
        const time2 = await step3(time1);
        const result = await step3(time1);
        console.log(`result is ${result}`); // YYDS
        console.timeEnd("testAsync");
    }

    testAsync();

async/await有多清晰,不用多说了吧。

附庸风雅😳😳😳

梅花引 荆溪阻雪 蒋捷

白鸥问我泊孤舟

是身留?是心留?

心若留时,何事锁眉头?

风拍小帘灯晕舞

对闲影,冷清清,忆旧游。

旧游旧游今在不?

花外楼,柳下舟。

梦也梦也,梦不到,寒水空流。

漠漠黄云,湿透木棉裘。

都道无人愁似我

今夜雪,有梅花,似我愁。

posted @ 2022-03-27 23:42  于北往南  阅读(207)  评论(2编辑  收藏  举报