Co 流程流程控制器源码与理解,index.js 包含理解和注释
这个版本是重点是理解 generator 工作原理
// @flow
/**
* Created by Freax on 16-12-12.
* @Blog http://www.myfreax.com/
*/
function co(generator) {
let gen = generator();
next(gen.next()); //递归遍历 generator.next
function next(result) {
if (result.done)return null;//如果 generator 执行完毕,直接解决退出遍历
let res = gen.next(result.value);
next(res);
}
}
co(function *gen() {
let a = yield 1;
console.info(a, 'a');
let b = yield 2;
console.info(b, 'b');
let c = yield 3;
console.info(c, 'c');
});
理解 generator+promise 如何工作
// @flow
/**
* Created by Freax on 16-12-12.
* @Blog http://www.myfreax.com/
*/
function isPromise(obj) {
return typeof obj === 'object' && 'function' == typeof obj.then;
}
function co(generator) {
return new Promise((resolve,reject)=>{
let gen = generator();
next(gen.next());
function next(result) {
if (result.done)return resolve(result.value);//如果 generator 执行完毕,直接解决退出遍历
//判断是否是 Promise ,如果是 promise 则执行 promise 再进入 next 递归遍历 generator.next
if (isPromise(result.value))return result.value.then(res => {
let result;
try {
result = gen.next(res); //抛出 generator 的错误
}catch (e){
return reject(e);// 捕获后由交给 promise 处理返回外部处理
}
next(result)
}, err => {
let result;
try {
result = gen.throw(err); //yield 返回 promise 进入 reject 后的错误,抛出 generator 的错误
}catch (e){
return reject(e); // 捕获后由交给 promise 处理返回外部处理
}
next(result)
});
let res = gen.next(result.value);
next(res);
}
});
}
co(function *gen() {
let a = yield Promise.resolve(1);
console.info(a, 'a');
let b = yield 2;
console.info(b, 'b');
let c = yield 3;
console.info(c, 'c');
}).catch((err)=>{
console.info(err);
});
1
iugo 2016-12-13 14:29:34 +08:00
我对此有点模糊.
不过想要全面理解 generators 还是要先理解 iterators. |
2
huangyanxong OP @iugo generator 调用 generators 后返回的是可遍历迭代器,这个迭代器有个 next 的方法,方法返回的是一个对象{done:false,value:1},对象的 done 属性的 true 代表已经遍历完毕
|