javascript

async await詳解

asyncawait本身就是promise+generator的語法糖。

>

async await 本身就是 promise + generator 的語法糖。

本文主要講述以下內容

  1. async awiat 實質
  2. async await 主要特性

async await 實質

下面使用 promise + generate 實現 async await

// 轉換目標 async1
    // async function async1() {
    //    console.log('async1 start');
    //    await async2();
    //    console.log('async1 end');
    // }

    function async1() {
        // 將 async 轉換成 *,將 awiat 轉換成 yield
        var awaitInstance = (function* () {
            console.log('async1 start');
            yield async2();
            console.log('async1 end');
        })()

        // 自動執行 await 及後續程式碼
        // 簡單起見,不處理異常情況
        function step() {
            var next = awaitInstance.next();
            // 使用Promise獲取 非同步/同步 方法的結果,再執行下一步
            Promise.resolve(next.value).then(function (val) {
                if (!next.done) step();
            })
        }
        step();

        // 返回Promise
        return Promise.resolve(undefined);
    }

async await 特性

  1. async 一定會返回 promise
// 案例1: 不設定return
    async function fn() {}
    fn().then(alert); // alert -> undefined

    // 案例2:return非promise
    async function f() {
        return 1
    }
    f().then(alert); // alert -> 1

    // 案例3: return Promise
    async function fn() {
        return Promise.resolve(2);
    }
    fn().then(alert); // alert -> 2
  1. async 中程式碼是直接執行的(同步任務)
console.log(1);

    async function fn() {
        console.log(2);
        await console.log(3)
        console.log(4)
     }
    fn();

    console.log(5);

    // 列印 1 2 3 5 4
    // 為何後面是 3 5 4 ? 往下看
  1. await是直接執行的,而await後面的程式碼是 microtask。
async function async1() {
        console.log('async1 start');
        await async2();
        console.log('async1 end');
    }

    // 類似於
    async function async1() {
        console.log('async1 start');
        Promise.resolve(async2()).then(() => {
            console.log('async1 end');
        })
    }
  1. await後面程式碼會等await內部程式碼全部完成後再執行
async function async1() {
        console.log('async1 start');
        await async2();
        console.log('async1 end');
    }

    async function async2() {
        return new Promise(function(resolve) {
            setTimeout(function() {
                console.log('sleep 2s');
                resolve('do');
            }, 2000)
        })
    }

    async1();

    // 列印結果
    // async1 start -> sleep 2s -> async1 end
  1. await 操作符用於等待一個Promise 物件。它只能在非同步函式 async function 中使用。參考 MDN
附:
    在chrome版本 73.0.3683.8664 位)中,
    await是可以直接使用的。

    var x = await console.log(1)
Facebook Profile photo
Written by Nat
This is the author box. A short description about the author of this article. Could be their website link, what they like to read about and so on. Profile