async await 原理

一、async await具体使用规则

(1)async的函数在执行后都会自动返回一个Promise对象,有无值根据有无return值。

(2)await必须在async函数里使用,不能单独使用。

(3)await后面需要跟Promise对象,不然就没有意义,而且await后面的Promise对象不必写then,因为await的作用之一就是获取后面Promise对象成功状态传递出来的参数。

(4)async/await作用是用同步方式,执行异步操作。

二、generator函数

(1)跟普通函数在写法上的区别就是,多了一个星号*

(2) yield:只有在generator函数中才能使用yield。相当于generator函数执行的中途停站点。

(3)next方法:执行后会返回一个对象,对象中有value和done两个属性。

  • value:暂停点后面接的值,也就是yield后面接的值(最后一个是undefined,这取决于generator函数有无返回值)
  • done:是否generator函数已走完,没走完为false,走完为true

(4)generator函数可以用next方法来传参,并且可以通过yield来接收这个参数,注意两点

  • 第一次next传参是没用的,只有从第二次开始next传参才有用
  • next传值时,要记住顺序是,先右边yield,后左边接收参数
function* gen() {
  const num1 = yield 1
  console.log(num1)
  const num2 = yield 2
  console.log(num2)
  return 3
}
const g = gen()
console.log(g.next()) // { value: 1, done: false }
console.log(g.next(11111))
// 11111
//  { value: 2, done: false }
console.log(g.next(22222)) 
// 22222
// { value: 3, done: true }

三、async await 原理(generator+自动执行器)

function fn(nums) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(nums * 2)
    }, 1000)
  })
}
function* gen() {
  const num1 = yield fn(1)
  console.log(num1) // 2
  const num2 = yield fn(num1)
  console.log(num2) // 4
  const num3 = yield fn(num2)
  console.log(num3) // 8
  return num3
}
function generatorToAsync(generatorFn) {
  return function() {
    const gen = generatorFn.apply(this, arguments) // gen有可能传参

    // 返回一个Promise
    return new Promise((resolve, reject) => {

      function go(key, arg) {
        let res
        try {
          res = gen[key](arg) // 这里有可能会执行返回reject状态的Promise
        } catch (error) {
          return reject(error) // 报错的话会走catch,直接reject
        }

        // 解构获得value和done
        const { value, done } = res
        if (done) {
          // 如果done为true,说明走完了,进行resolve(value)
          return resolve(value)
        } else {
          // 如果done为false,说明没走完,还得继续走
          // value有可能是:常量,Promise,Promise有可能是成功或者失败
          return Promise.resolve(value).then(val => go('next', val), err => go('throw', err))
        }
      }

      go("next") // 第一次执行
    })
  }
}

const asyncFn = generatorToAsync(gen)

asyncFn().then(res => console.log(res))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值