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);
});
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.