简述一下 Generator 函数
传统的编程语言,早有异步编程的解决方案(其实是多任务的解决方案)。其中有一种叫做“协程”(coroutine),意思是多个线程互相协作,完成异步任务。
协程有点像函数,又有点像线程,它的运行流程大致如下:
- 第一步,协程
A开始执行; - 第二步,协程
A执行到一半,进入暂停,执行权转移到协程B; - 第三步,(一段时间后)协程
B交还执行权; - 第四步,协程
A恢复执行;
上面流程的协程 A,就是异步任务,因为它分成两段(或多段)执行。
举例来说,读取文件的协程写法如下:
js
function* asyncJob() {
// ...
var f = yield readFile(fileA);
// ...
}上面代码的函数 asyncJob 是一个协程,它的奥妙就在其中的 yield 命令。它表示执行到此处,执行权将交给其他协程。也就是说,yield 命令是异步两个阶段的分界线。协程遇到 yield 命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。
Generator 函数是协程在 ES6 的实现,最大特点就是可以交出函数的执行权(即暂停执行)。
js
function* gen(x) {
var y = yield x + 2;
return y;
}
var g = gen(1);
g.next() // { value: 3, done: false }
g.next(2) // { value: 2, done: false }next 是返回值的 value 属性,是 Generator 函数向外输出数据;next 方法还可以接受参数,向 Generator 函数体内输入数据。
上面代码中,第一个 next 方法的 value 属性,返回表达式 x + 2 的值 3。第二个 next 方法带有参数 2,这个参数可以传入 Generator 函数,作为 上个阶段 异步任务的返回结果,被函数体内的变量 y 接收。因此,这一步的 value 属性,返回的就是 2(变量 y 的值)。