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 
}
  • 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();

在这里插入图片描述

再来两个例子:

async function test1(){
    // 返回任何值会默认异步成功,也会修改为成功状态
    return 1;
};
async function test2(){
 // 抛出任何值会默认异步失败,也会修改为失败状态
    throw 2;
};

test1();
test2();

在这里插入图片描述

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

    async function test3(){
        return  Promise.resolve(3);
    };

    async function test4(){
        return  Promise.reject(4);
    };

在这里插入图片描述

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

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

await

官网说到:

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

看一下格式:

[返回值] = await 表达式;
  • 表达式
    一个 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)
    }

在这里插入图片描述

虽然可以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)
    }

在这里插入图片描述

又有一个神奇问题,上面返回值可以和返回一个成功状态的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)
    }

在这里插入图片描述

可以看出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)
        }
    }

在这里插入图片描述

所以:如果一个错误状态的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);
}

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

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

在这里插入图片描述

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

async function test_async(){
    var return1=await step1(1);
    var return2=await step2(return1);
    var return3=await step2(return2);    
}
test_async()

在这里插入图片描述

是看着会更具舒服一些。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值