zoukankan      html  css  js  c++  java
  • async/await的使用以及注意事项

    使用 async / await, 搭配 promise, 可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性. 本文介绍 async / await 的基本用法和一些注意事项.

    await

    引用MDN的介绍:

    await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用.

    await 的使用语法非常简单:

    [return_value] = await expression;

    其中 expression 是一个 Promise 对象或者任何要等待的值;

    而 await expression 的执行结果有以下几种情况:

    1. 若 expression 是一个 Promise 对象, 并且其以值 x 被 fulfilled, 则返回值为 x.

    2. 若 expression 是一个 Promise 对象, 并且其以异常 e 被 rejected, 则抛出异常 e.

    3. 若 expression 不是 Promise 对象, 则会将 expression 处理成一个以 expression 值被 fulfilled 的 Promise 对象, 然后返回这个 Promise 对象的最终值 (即 expression 值). 这种用法没太大意义, 因此实际使用时还是尽量在 await 后跟一个 Promise 对象.

    4. 另外需要注意的是, await 在等待 Promise 对象时会导致 async function 暂停执行, 一直到 Promise 对象决议之后才会 async function 继续执行.

      通过一段代码来看一下:

    async function foo() {
        var a = await new Promise((resolve) => {
            setTimeout(() => {
                resolve(1);
            }, 2000);
        });
        console.log(a); // 第2秒时输出: 1
    
        try {
            var b = await new Promise((resolve, reject) => {
                setTimeout(() => {
                    reject(2);
                }, 1000);
            })
        } catch (e) {
            console.log(e); // 第3秒时输出: 2
        }
    
        // 函数暂停2秒后再继续执行
        var sleep = await new Promise((resolve) => {
            setTimeout(() => {
                resolve('sleep');
            }, 2000);
        });
    
        var c = await 3;
        console.log(c); // 第5秒时输出: 3
    }
    
    foo();
    

      

    async

    使用 async function 可以定义一个 异步函数, 语法为:

    async function name([param[, param[, ... param]]]) { statements }

    async 函数的返回值很特殊: 不管在函数体内 return 了什么值, async 函数的实际返回值总是一个 Promise 对象. 详细讲就是:

    若在 async 函数中 return 了一个值 x, 不管 x 值是什么类型, async 函数的实际返回值总是 Promise.resolve(x).

    那么 Promise.resolve(x) 最终返回一个什么样的promise呢? 来看一下MDN的介绍:

    Promise.resolve(value)方法返回一个以给定值解析后的Promise对象。但如果这个值是个thenable(即带有then方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态(指resolved/rejected/pending/settled);否则以该值为成功状态返回promise对象。

    接下来看一段代码的应用. 假设有这样一个场景: 需要先通过 请求1 拿到 数据1, 然后通过通过 请求2 并携带发送 数据1 获取到 数据2, 拿到 数据2 之后再展示到页面.

    方案一:

    async function showData() {
        // 假装请求数据1
        var data1 = await new Promise((resolve) => {
            setTimeout(() => {
                resolve('data1');
            }, 1000);
        });
    
        // 假装请求数据2且此请求依赖数据1
        var data2 = await new Promise((resolve) => {
            setTimeout(() => {
                resolve('data2');
            }, 1000);
        });
    
        // 展示数据2
        console.log(data2);
    }
    
    showData();
    

      

    上面这段代码是依次获取到 数据1 和 数据2, 然后再展示 数据2.

    既然 async 函数总是返回一个promise, 那么也可以在一个 async 函数返回获取 数据2 的promise, 调用函数后再使用 then方法拿到数据, 代码如下:

    async function getData() {
        // 假装请求数据1
        var data1 = await new Promise((resolve) => {
            setTimeout(() => {
                resolve('data1');
            }, 1000);
        });
    
        // 假装请求数据2且此请求依赖数据1
        return new Promise((resolve) => {
            setTimeout(() => {
                resolve('data2');
            }, 1000);
        });
    }
    
    getData().then((v) => {
        console.log(v);
    });
    

      转自:https://blog.csdn.net/juhaotian/article/details/78934097
    https://segmentfault.com/a/1190000010244279

  • 相关阅读:
    图片上传
    解决Vuex持久化插件-在F5刷新页面后数据不见的问题
    vue登录
    拖动排序的vue组件
    vue图片懒加载
    vue中使用图片预加载
    前端架构知识体系
    html判断IE版本
    HighCharts 在IE8下饼图不显示的问题
    新一代调试王者Console
  • 原文地址:https://www.cnblogs.com/laneyfu/p/9262114.html
Copyright © 2011-2022 走看看