盒子
盒子

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函数,就会自动执行。

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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吧!!!