async/await的正確使用


最佳實踐

經過一段時間的使用,對於async/await的正確使用,我總結了一下幾點:

  1. 必須使用 try...catch。確保正確的流程控制。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // resolve
    function getData() {
    return new Promise((resolve, reject) => {
    setTimeout(() => resolve({ state: 1 }), 1000);
    });
    }
    // reject
    function getData() {
    return new Promise((resolve, reject) => {
    setTimeout(() => reject({ error: 2 }), 1000);
    });
    }

    async function hello() {
    let data = await getData();
    console.log(data.state);
    }

    async function hello() {
    try {
    let data = await getData();
    console.log(data.state);
    } catch (e) {
    console.log(e);
    let data = {};
    }
    }

    hello();

    如果await后面的promise返回的是reject,那么下面的同步代碼不會執行。所以必須使用try...catch,如果出現這種情況,
    會進入catch,執行錯誤處理代碼。

  2. 多重嵌套時,內層的try...catch必須有返回值,且catch中的返回值是Promise.reject。返回值是promise

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // resolve
    function getData() {
    return new Promise((resolve, reject) => {
    setTimeout(() => resolve({ state: 1 }), 1000);
    });
    }
    // reject
    function getData() {
    return new Promise((resolve, reject) => {
    setTimeout(() => reject({ error: 2 }), 1000);
    });
    }

    async function hello() {
    try {
    return await getData();
    } catch (e) {
    console.log(`${e} --- hello catch`);
    return Promise.reject(e);
    // return Promise.resolve(e)
    }
    }

    async function world() {
    try {
    // 不會執行
    data = await hello();
    } catch (e) {
    data = {};
    console.log(`${e} --- world catch`);
    }
    }
    world();

    world使用異步方式調用了hello,如果hello中的getData方法拋出了錯誤,會進入hello里的catch,則catch中也必須有返回值,否則,將不會進入world中的catch,而是繼續執行try里面的代碼;如果使用了Promise.resolve返回內容或者返回內容不是Promise,就也是執行try里面的代碼;只用返回的結果是Promise且為Promise.reject,才會正常的進入world中的catch

  3. vue 的生命周期是獨立的,不會受到異步函數的影響。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    export default {
    data() {
    return {
    data: null
    };
    },
    async created() {
    this.data = await this.getData();
    },
    mounted() {
    console.log(this.data);
    },
    methods: {
    getData() {
    return new Promise((resolve, reject) => {
    setTimeout(() => resolve({ state: 1 }), 1000);
    });
    }
    }
    };

    我們知道created函數會早於mounted被調用,但是mounted並不會等待created中的異步函數,vue的生命周期只跟其內部的執行流程有關,不受外界的影響。

總結

就如我一開始所說,async/await並不是什么新的技術,而只是語法糖。
但是,如果要替代現在的promise,特別是在多人團隊中推廣,我還是建議先去學習一下語法,尤其是異常處理和多層嵌套下向外拋出異常,不然,….說多了都是坑 😂。
這篇文章只是講了async/await的具體實踐,如果你想了解promiseasync/await的實現原理,請移步Promise實現原理 🌑 從Promise到async/await 🌑


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM