• JavaScript新特性 async和await


    前面聊了promise,如果不懂的话可以翻看一些前面的文章:传送门

    着两个关键字一般都是成对出现的,所以本篇聊一下。

    async一般用来修饰函数的,其修饰的函数称为变成async函数。而在这个函数中可以使用await关键字。

    因此:await必须写在async函数中,但是async函数中可以没有await。

    现在看一下async和await两个关键字各有什么神奇的作用呢,下面依次演示。

    async

    首先看一下官网的解释:

    async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。

    现在看一下格式:

    async function name([param[, param[, ... param]]]) {
        statements 
    }
    
    • 1
    • 2
    • 3
    • name

      函数名称。

    • param

      要传递给函数的参数的名称。

    • statements

      包含函数主体的表达式。可以使用await机制。

      async函数的函数体可以被看作是由0个或者多个await表达式分割开来的。从第一行代码直到(并包括)第一个await表达式(如果有的话)都是同步运行的。这样的话,一个不含await表达式的async函数是会同步运行的。然而,如果函数体内有一个await表达式,async函数就一定会异步执行。

    • 返回值

      返回值是一个promise,这个promise要么会通过一个由async函数返回的值被解决,要么会通过一个从async函数中抛出的(或其中没有被捕获到的)异常被拒绝。async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中.

    老规矩演示:

    async function test_async(){
        // 这里结果就是将return注释取消结果也不会变  默认就是return 一个undefined 
        //return;
    };
    test_async();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    再来两个例子:

    async function test1(){
        // 返回任何值会默认异步成功,也会修改为成功状态
        return 1;
    };
    async function test2(){
     // 抛出任何值会默认异步失败,也会修改为失败状态
        throw 2;
    };
    
    test1();
    test2();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    可以看出如果是返回的就是promise呢?

        async function test3(){
            return  Promise.resolve(3);
        };
    
        async function test4(){
            return  Promise.reject(4);
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    因为async返回的是promise,自然可以跟then等方法,这个就不再具体演示了,可以看前面聊promise中对then等方法的演示。

    而async的神奇操作更多的依靠await关键字,所以这里简单演示用法,后面结合await具体聊。

    await

    官网说到:

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

    看一下格式:

    [返回值] = await 表达式;
    
    • 1
    • 表达式
      一个 Promise 对象或者任何要等待的值。

    • 返回值

      返回 Promise 对象的处理结果。简单的理解可以是:await表达式之后的代码可以被认为是存在在链式调用的then回调中,多个await表达式都将加入链式调用的then回调中,返回值将作为最后一个then回调的返回值。

      如果等待的不是 Promise 对象,则返回该值本身。

    补充:

    await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理(fulfilled),其回调的resolve函数参数作为 await 表达式的值,继续执行 async function。若 Promise 处理异常(rejected),await 表达式会把 Promise 的异常原因抛出。另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。

    演示一个:

       function  test_f1(val) {
          return new Promise((resolve,reject)=>{
                setTimeout(()=>{
                 resolve(val)
            },1000)
          })
    
        }
    
        async function test_1() {
          var test_value=test_f1('test_1').then((value)=>{
               console.log('test_1----',value)
          });
          console.log('test1中 调用test_f1的后面');  
           
        }
    
        async function test_2() {
          var test_value=await test_f1('test_2');
          console.log('test2中 调用test_f1的后面');    
          console.log('test_2----',test_value)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    虽然可以await可以等待这个封装在promise异步操作结果,而then却不会。

    前面又说道如果等待的不是 Promise 对象,则返回该值本身。

    如下演示:

       function  test_f1(val) {
          return  val;
     
    
        }
    
        async function test_2() {
          var test_value=await test_f1('test_2');   
          console.log('test_2----',test_value)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    又有一个神奇问题,上面返回值可以和返回一个成功状态的promise都可以理解为成功状态,但是难道await后面执行的一定都会成功状态吗?

    function  test_f1(val) {
          // 不再重复代码,这里写throw val  显示结果不会变
           return Promise.reject(val);
    
        }
    
        async function test_2() {
          var test_value=await test_f1('test_2');
          console.log('test_2----',test_value)
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    可以看出await无法得到一个错误状态的Promise对象(或throw 错误对象或者数值,而这个就需要通过try–catch才可以得到这个错误值。

        function  test_f1(val) {
            // 不再重复代码,这里写throw val  显示结果不会变
            return Promise.reject(val);
    
        }
    
        async function test_2() {
            try{
                var test_value=await test_f1('test_2');
            }catch  (error){
                console.log('test_2----',error)
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    所以:如果一个错误状态的promise对象(或者throw ),那就会抛出异常,需要通过try-catch来捕获。

    优点

    既然是新特性,那么async和await关键字自然尤其优势。promise最牛逼之一可以写出一个链式操作如下:

    function test(n) {
     return new Promise(resolve => {
       setTimeout(() => resolve(n+1));
     });
    }
     
    function step1(n) {
     console.log(`第一步`,n);
     return test(n);
    }
     
    function step2(n) {
     console.log(`第二步`,n);
     return test(n);
    }
     
    function step3(n) {
     console.log(`第三步`,n);
     return test(n);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    如果通过then进行链式调用:

    step1(1).then((value=>step2(value))).then((value=>step3(value)))
    
    • 1

    在这里插入图片描述

    然后永async和await关键字试一下。

    async function test_async(){
        var return1=await step1(1);
        var return2=await step2(return1);
        var return3=await step2(return2);    
    }
    test_async()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    是看着会更具舒服一些。

  • 相关阅读:
    行列转换:MySQL中的数据变形魔法
    Spring中实现AOP的功能
    瑞吉外卖 —— 11、项目优化:使用 Redis 缓存
    HTML+CSS个人静态网页设计
    计算机毕设 深度学习 大数据 股票预测系统 - python lstm
    【软件测试】05 -- 软件测试的原则
    【淘宝开店】新手入门开网店教程
    第3章业务功能开发(线索关联市场活动,动态搜索)
    手把手带你配置一个DHCP服务器
    爱上开源之golang入门至实战第三章-性能分析-分析数据
  • 原文地址:https://blog.csdn.net/u011863822/article/details/124931055