zoukankan      html  css  js  c++  java
  • ES6 之 async函数

    1.简介

    ES2017引入了async函数,使得异步操作变得更加方便。

    async函数的返回值是Promise对象,因此可以使用.then()方法指定下一步操作。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体后面的语句。

    示例:

    function timeout(ms){
      return new Promise((reslove)=>{
        setTimeout(reslove,ms);
      });
    }
    
    async function asyncPrint(value,ms) { 
      await timeout(ms);
      console.log(value);
    }
    
    asyncPrint('hello world',2000);

    以上代码指定2s后输出"hello world"

    由于async 函数返回的是Promise对象,可以作为await命令的参数,上面的例子也可以写成:

    async function timeout(ms) { 
      await new Promise((resolve)=>{
        setTimeout(resolve,2000);
      })
    }
    
    async function asyncPrint(value,ms) { 
      await timeout(ms);
      console.log(value);
    }
    
    asyncPrint('hello world',2000)

    2.async的使用方式:

    (1)函数声明:

    async function foo(){...}

    (2)函数表达式

    const foo = async function(){...}

    (3)对象的方法

    let obj = { async foo() {} };
    obj.foo().then(...)

    (4)class的方法

    class Storage{
        constructor (){
        this.catchePromise = caches.open("avatars");  
      }

      async getAvatar(name) {
        const cache = await this.cachePromise;
        return cache.match("/avatars/${name}.jpg");
      } }


    const storage = new Storage();
    storage.getAvatar("'jack").then(...

    3.语法

    async函数内部return语句返回的值,会成为.then方法回调函数的参数。

    async function f(){
      return "hello";
    }
    
    f().then(v => console.log(v));

    上面代码中,f函数返回的字符串被then接到,再进行操作。

    async函数内部抛出错误会导致返回的Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数截到

    async function f(){
      throw new Error("出错了");
    }
    
    f().then(
      v => console.log(v),
      e => console.log(e)
    );

    注意:async函数返回的Promise对象必须等到内部所有await命令后面的Promise对象执行完才会发生状态改变,除非玉带return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

    4.await命令

    正常情况下,await命令后面是一个Promise对象,如果不是,会被转成一个立即resolve的Promise对象。

    async function f(){
      return await 123;
    }
    
    f().then(v => console.log(v));

      上面的代码中,await命令的参数是数值123,它被转成Promise对象并立即resolve。

    await命令后面的Promise对象如果变成reject状态,则reject的参数会被catch方法的回调函数接到。

    async function f(){
      await Promise.reject("出错了");
    }
    
    f()
    .then(v => console.log(v))
    .catch(e => console.log(e));  // 出错了

    上面的代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。

    值得注意的是:只要一个await语句后面的Promise变为reject,那么整个async函数都会中断执行。

    async function f(){
      await Promise.reject("出错了");
      await Promise.resolve("hello world");    // 不会执行
    }
    
    f()
    .then(v => console.log(v))
    .catch(e => console.log(e));

    如果希望一个异步操作执行失败也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

    async function f(){
      try{
        await Promise.reject("出错了");
      }catch{
    
      }
      return await Promise.resolve("hello world");
    }
    
    f().then(v => console.log(v));

    或者:也可以在await后面的Promise对象后变价一个catch()方法,处理前面可能出现的错误。

    async function f(){
      await Promise.reject("出错了")
      .catch(e => console.log(e));
      return await Promise.resolve("hello world");
    }
    
    f().then(v => console.log(v));
    
    // 出错了
    // hello world

    5.错误处理

    如果await后面的异步操作出错,那么等同于async函数返回的Promise对象被reject。

    处理出错的方法上面已经提出两种。

    如果有多个await命令,则可以统一放在try ... catch结构中。

    所以,await命令后面的Promise对象的运行结果可能是rejected,所以最好把await命令放在 try...catch代码块中。

  • 相关阅读:
    【算法】一致性Hash算法
    P1576 最小花费 题解
    Vijos1234 口袋的天空 题解
    P1379 八数码难题 题解
    Tarjan求无向图必经点 笔记
    P3372 【模板】线段树 1 题解
    CF1332A Exercising Walk 题解
    P6270 [SHOI2002]取石子游戏 题解
    P6269 [SHOI2002]空中都市 题解
    P6268 [SHOI2002]舞会 题解
  • 原文地址:https://www.cnblogs.com/codexlx/p/12589451.html
Copyright © 2011-2022 走看看