es6——async / await

ES6中的async/await是Generator函数的语法糖,提供了内置执行器,使得异步操作更加简洁。async函数的特点包括:无需额外执行器、更好的语义、更广泛的使用性,以及返回Promise对象。在async函数中,await命令后面可以是Promise或原始值,且当await后的Promise被reject时,可以使用try...catch捕获错误。多个await命令会依次执行,若前一个出现错误,后续的await将停止执行。

首先,async / await是什么?简单来说,它就是 Generator 函数的语法糖

特点:

  • 内置执行器
    Generator 函数执行必须靠执行器,所以才有了 co 模块,而 async 函数自带执行器,也就是说 async 函数的执行与普通函数一摸一样,只要一行
  • 更好的语义
    async 和 await 比起星号和 yield,语义更加清晰,async 表示函数里有异步操作,await 表示紧跟在后面的表达式需要等待结果
  • 更广的使用性
    co 模块约定,yield 命令后面只能是 Thunk 函数或 Promise 对象,而 async 函数的 await 命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)
  • 返回值是 Promise
    async 函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便许多,可以 then 和 catch 方法指定下一步操作
    进一步说,async 函数可以看作由多个异步操作包装成的一个 Promise 对象,而 await 命令就是内部 then 命令的语法糖

async 函数多种形式

  // 函数声明
  async function foo () {}

  // 函数表达式
  const foo = async function () {}

  // 对象的方法
  let obj = { async foo () {} }
  obj.foo().then()

  // Class 的方法
  class Storage {
    constructor () {
      this.cachePromise = caches.open('avatars')
    }

    async getAvatar (name) {
      const cache = await this.cachePromise
      return cache.match(`/avatar/${name}.jpg`)
    }
  }

  const storage = new Storage()
  storage.getAvatar('jake').then()

  // 箭头函数
  const foo = async () => {}

async 用法

  async function asyncFun () {
    let name = await db.get(name)
    let result = await db.get(name)
    return result
  }

  asyncFun()
    .then(res => {
      console.log(res)// 返回 return 的 result
    })
    .catch(err => {
      console.log(err)// 发生错误在这里捕获
    })

async 函数中间一步 await 出错或遇到 return,后面的 await 都会停止执行,抛出的错误对象会被 catch 方法回调函数接收到

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

  // 结合 try ... catch 使用
  async function asyncFun () {
    try {
      let name = await db.get(name)
      let result = await db.get(name)
      return result
    } catch (e) {
      console.log(e)// 发生错误在这里捕获
    }
  }

  asyncFun().then(res => {
    console.log(res)// 返回 return 的 result
  })

多个 await 命令后面的异步操作如果不存在继发关系,最好让它们同时触发

    // 这种执行方式,由于 getFoo 和 getBar 是两个独立的异步操作(互不依赖)
    // 被写成继发关系,比较耗时,只有 foo 完成后才会执行 bar
    let foo = await getFoo()
    let bar = await getBar()

	// 解决的两种方式:
    // 写法一
    let [foo, bar] = await Promise.all([getFoo(), getBar()])

    // 写法二
    let fooPromise = getFoo()
    let barPromise = getBar()
    let foo = await fooPromise
    let bar = await barPromise
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值