• JavaScript(五):优雅的async/await


    1、概述

    大家好,我是欧阳方超。
    本次看一下async/await的使用。

    2、async/await

    async/await是基于Promise的,可以说是Promise的语法糖

    2.1、async关键字

    async关键字一般会放在函数前面,这会使得函数返回一个Promise对象:

    async function testFunction() {
            return "async";
        }
    
    • 1
    • 2
    • 3

    这等效于下面的代码:

    function testFunction() {
            return Promise.resolve("async");
        }
    
    • 1
    • 2
    • 3

    调用上面的两个testFunction()函数都会返回Promise对象,接着就能使用Promise的相关函数了:

    function testFunction() {
            return Promise.resolve("async");
        }
        testFunction().then((value)=>{console.log(value)});
    
    • 1
    • 2
    • 3
    • 4

    可以看出在我们不写任何关于Promise的内容时,async关键字已经帮我们返回了Promise对象;与async搭配使用的还有一个关键字——await,它可以帮助我们在不使用then()函数时也能达到同样的目的。

    2.2、await关键字

    await关键字只能用在async函数内部或JavaScript模块中。其语法如下:

    let value = await expression;
    
    • 1

    其中expression一般是一个Promise对象,或是其他任何需要等待的值。
    await运行机制
    await关键字会导致async函数暂停执行,直到Promise对象变为settled状态(包括fulfilled或rejected),async函数才会恢复执行;当恢复执行时,await expression 的值是状态为fulfilled的Promise对象的value值,如果Promise对象的状态为rejected,await表达式会把异常原因抛出。

    Promise对象状态为fulfilled的示例:

    async function testFunction() {
    
        let promise = new Promise((resolve, reject)=>{
            setTimeout(()=>{resolve("ok")}, 3000);
        });
    
        let res = await promise;
        console.log(res);
    }
    
    testFunction();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上面示例中,调用testFunction()后,程序执行到await promise这一行时,会“暂停”不在往下执行,一直等到3秒后,resolve()被调用了,Promise对象的状态变为fulfilled,res变量才会拿到调用resolve()函数时传入的参数。注意,这种暂停只是发生在testFunction()函数内部,并不影响函数外其他代码的执行,毕竟testFunction()是一个async function,它不会阻塞其他任务。

    Promise对象状态为rejected的示例:

    async function testFunction() {
    
        try {
            let promise = new Promise((resolve, reject)=>{
                setTimeout(()=>{reject(new Error("异常"))}, 3000);
            });
            let res = await promise;
            console.log("本行不再执行");
        } catch (err) {
            console.log(err);
        }
    
    }
    testFunction();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    console中的执行结果:
    在这里插入图片描述上面示例中,promise对象的状态因调用了reject()而变成了rejected,当执行到await promise时,异常原因会被抛出,被catch捕获到,在try中,当异常发生时,出现在发生异常之后的代码都不会得到执行。

    await后不是Promise对象
    如果await关键字后跟的表达式的值不是一个Promise对象,则返回该值本身,如下:

    async function testFunction() {
    
        let promise = await 20;
        console.log(promise);
    
    }
    testFunction();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、总结

    async关键字在函数前面有两个作用:

    1. 让这个函数始终返回一个Promise对象;
    2. 可以在函数内使用await关键字;
      promise前的await关键字使得JavaScript暂停async函数中下面代码的执行,一直等待promise状态变为settled,之后:
    3. 如果是一个错误,会产生异常——就像那里调用了throw error一样;
    4. 否则就返回正常结果。

    async/await关键字为编写易于读写的异步代码提供了较好的方式,我们可以几乎不再使用promise.then/catch方法,但是我们应该始终牢记这两个关键字时基于promise的,有些场景下还是需要使用的;另外当需要同时等待多个任务时,使用Promise.all不失为一个好办法。

    我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。

  • 相关阅读:
    JavaIO系列——常见字符编码,字符流抽象类,FileReader,FileWriter
    国产华为设备:NAT地址转换实验
    ES6 字符串的repeat()方法
    窄边极简折叠玻璃门,实现自由推拉及折叠,遥控随意切换透明与磨砂效果
    计算首屏时间
    Scrapy08:scrapy-deltafetch,让爬虫有了记忆
    Mac下安装Nginx
    华为智慧屏 招一招即可分享运动状态,搜索运动教程,同时还可通过手机操控智慧屏
    如何在Blender中压缩/减小GLTF模型的大小
    Django系列7-员工管理系统实战--项目准备
  • 原文地址:https://blog.csdn.net/u012288582/article/details/126709609