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有多清晰,不用多說了吧。

附庸風雅😳😳😳

梅花引 荊溪阻雪 蔣捷

白鷗問我泊孤舟

是身留?是心留?

心若留時,何事鎖眉頭?

風拍小簾燈暈舞

對閒影,冷清清,憶舊遊。

舊遊舊遊今在不?

花外樓,柳下舟。

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

漠漠黃雲,溼透木棉裘。

都道無人愁似我

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章