# 如何实现一个 async/await

Issue

欢迎在 Issue 中交流与讨论: Issue 241

Author

回答者: sl1673495

/**
 * async的执行原理
 * 其实就是自动执行generator函数
 * 暂时不考虑genertor的编译步骤(更复杂)
 */

const getData = () =>
  new Promise(resolve => setTimeout(() => resolve("data"), 1000))

// 这样的一个async函数 应该再1秒后打印data
async function test() {
  const data = await getData()
  console.log('data: ', data);
  const data2 = await getData()
  console.log('data2: ', data2);
  return 'success'
}

// async函数会被编译成generator函数 (babel会编译成更本质的形态,这里我们直接用generator)
function* testG() {
  // await被编译成了yield
  const data = yield getData()
  console.log('data: ', data);
  const data2 = yield getData()
  console.log('data2: ', data2);
  return 'success'
}

function asyncToGenerator(generatorFunc) {
  return function() {
    const gen = generatorFunc.apply(this, arguments)

    return new Promise((resolve, reject) => {
      function step(key, arg) {
        let generatorResult
        try {
          generatorResult = gen[key](arg)
        } catch (error) {
          return reject(error)
        }

        const { value, done } = generatorResult

        if (done) {
          return resolve(value)
        } else {
          return Promise.resolve(value).then(
            function onResolve(val) {
              step("next", val)
            },
            function onReject(err) {
              step("throw", err)
            },
          )
        }
      }
      step("next")
    })
  }
}

const testGAsync = asyncToGenerator(testG)
testGAsync().then(result => {
  console.log(result)
})

扫码关注公众号全栈成长之路,并发送

即可在关注期间无限制浏览本站全部文章内容

你也可以在文章关于回复公众号扫码解锁全站的技术实现中获得解锁代码,永久解锁本站全部文章

Last Updated: 4/8/2020, 11:41:42 PM