ES7 async await

async await:用同步的方式来写异步
async函数返回一个 Promise 对象,可以使用then方法添加回调函数。函数内部return语句返回的值,会成为then方法回调函数的参数。
当async函数执行的时候,一旦遇到await就会先返回,等到await的异步操作完成,再接着执行函数体内后面的语句。

async getAPI (value, ms) {
  await new Promise((resolve, reject) => {
    setTimeout(resolve, ms)
    console.log(ms)
  })
   console.log(value)
}
//执行
this.getAPI('hello', 1000)
console.log('虽然在后面,但是我先执行')
//打印
1000
虽然在后面,但是我先执行
间隔一秒打印    hello

由于async函数返回的是一个Promise 对象。也可改为

async getOne(ms) {
        await new Promise((resolve, reject) => {
          setTimeout(resolve, ms)
          console.log(ms)
        })
      },
async getAPI(value, ms) {
        await this.getOne(ms)
        return value
      }
// 执行
this.getAPI('hello', 1000).then((res) => {
  console.log(res)
})
console.log('虽然在后面,但是我先执行')
// 打印结果一样

通常await后面的函数是一个promise 对象。我们可以直接运行async函数
如果await后面的函数不是一个promise,那他就会被转成 Promise 对象,并立即resolve成为async返回的promise里面的参数

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

await命令后面的 Promise 对象如果变为reject状态,则reject的参数会被catch方法的回调函数接收到。而resolve状态却不会被then方法接受(除非return)

async function f() {
  await Promise.reject('出错了');
}

f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出错了

只要有一个await语句后面的 Promise 变为reject,那么整个async函数都会中断执行。有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。所以最好把await命令放在try...catch代码块中。

async getTrycatch() {
        try {
          await Promise.reject('error')
        } catch (e) {}
        return await Promise.resolve('reslove')
      }
// 执行
this.getTrycatch().then((res) => {
        console.log(res)
      })

应用场景:多个异步接口的继发

async getTwo() {
        this.one = await getOne()
        console.log(this.one)
        this.two = await getTwo(this.one)
        console.log(this.two)
      }

多个接口的并发

let [one, two] = await Promise.all([getOne(), getTwo()])
this.one = one
this.two = two

多次重复尝试

const superagent = require('superagent');
const NUM_RETRIES = 3;

async function test() {
  for (let i = 0; i < NUM_RETRIES; i++) {
    try {
      await superagent.get('http://google.com/this-throws-an-error');
      break;
    } catch(err) {}
  }
  console.log(i); // 3
}
//上面代码中,如果await操作成功,就会使用break语句退出循环;如果失败,会被catch语句捕捉,然后进入下一轮循环。

总结:
1.如果是一个异步函数我们就可以在他的函数名前加一个async,将函数体里的return new promise改为await new promise
2.将await代码块放入try{}catch(e){}中
3.await默认是继发的,并发要使用Promise.all([...])
4.安装babel-polyfill解决不识别async await的问题

*知识来源于http://es6.ruanyifeng.com/#docs/async,谢谢阮一峰老师

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...
    呼呼哥阅读 7,334评论 5 22
  • 简单介绍下这几个的关系为方便起见 用以下代码为例简单介绍下这几个东西的关系, async 在函数声明前使用asyn...
    _我和你一样阅读 21,272评论 1 24
  • async 函数 含义 ES2017 标准引入了 async 函数,使得异步操作变得更加方便。 async 函数是...
    huilegezai阅读 1,278评论 0 6
  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 8,729评论 1 56
  • 相对于回调函数来说,Promise是一种相对优雅的选择。那么有没有更好的方案呢?答案就是async/await。优...
    松哥888阅读 47,498评论 8 36