sjn_hoho

sjn_hoho

Async Vs Generator

Async VS Generator

前文

Async 函数是 ES2017 中引入的标准,在 Node.js 于 7.6 默认支持,不再需要使用--harmony 参数。而 Generator 函数,则是在 ES2015 中引入,使 JavaScript 函数的异步进入了新的阶段,但是经过一定资料查询,笔者发现 async 函数其实就是 Generator 函数的语法糖。笔者工作的项目经历了从 Promise 到 Co+Generator 到 Async/Await 的转变。接下来就从实际代码中讲一讲感受到的这 2 者的区别。

正文

首先,最明显的区别就是一个的两者语法的区别,async 就是将*替换了,await 则是替换了 yield。然后就是另一个笔者认为最大的区别,async 函数默认返回的是一个 Promise,函数中的代码是会被执行的,但是 Generator 函数是不会自动执行的,需要一个自动执行机制,普遍的方案就是著名的 co 框架,将 Generator 函数传入 co 函数,就会自动执行。

const co = require('co')
co(gen)

但另外算是用 co 包装后也跟 async 存在差异。比如下面的代码,没有 yield

const co = require('co')
function delay() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log('3333')
      resolve(1)
    }, 1000)
  })
}
function* gen2() {
  let x = delay()
  return x
}
function* gen() {
  let x = gen2()
  console.log('gen', x)
  return x
}
co(gen())

会发现代码并不会执行,但是 async 不一样,忘了加 await,还是会异步执行的,笔者曾就遇到过忘记加 yield 的 bug,导致代码中断。这个区别就是 yield 和 await 的这 2 个操作符意义的区别。最后,既然提到 co 框架,还有个区别,就是在 co 框架中检查了 yield 后面跟的对象的类型,没有通过检查时会丢出 You may only yield a function, promise, generator, array, or object, but the following object was passed: "null"的 Error,但是 async/await 就没有这种困扰。

后文

JavaScript 的异步控制从 Callback,到 Promise,再到 Generator,Async/Await,变得越来越容易理解,但是最后的实质都是一样的。只能说内核开发者们好强啊,让更多的人拥抱 JS 吧!!!