Generator 特性
举个例子:
function* foo() {
yield 4;
var res = yield 2;
console.log("res:", res);
return 5;
}
var g = foo();
g.next(1); // { value: 4, done: false }
g.next(2); // { value: 2, done: false }
g.next(3); // res:3 { value: 5, done: true }
几点注意:
- 调用
foo()时,函数体中的逻辑并不会执行,直到调用g.next()时才会执行 - 调用
g.next()时返回{ value: *, done: * } - 当
done为false时,表示函数逻辑还未执行完 - 最后一次返回
return语句的结果,done为true var res = yield 2这句只执行了后面半段就暂停了,等到再次调用g.next(3)时才会将参数赋给res
co 模块原理
tj 大神的 co 模块就是建立在这些特性上的,核心思想是:
- Generator 函数中 yield 一个异步操作
- 异步操作完成后,将结果通过
next()传回 Generator - 递归执行直到 Generator 完成
这种模式让异步代码看起来像同步代码,后来 ES7 的 async/await 正是基于这个思想的语法糖。