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 🌑

posted @ 2020-09-22 14:41  风吹麦浪打  阅读(931)  评论(0编辑  收藏  举报