看了co的源码 比较难懂 了解了其原理后实现了一个最简版本https://github.com/yucong/simple-co 希望对想学习的tx有帮助~ yeild后面只支持thunk,co本身也是一个thunk 核心代码:
function co(generator) {
return function(fn) {
var gen = generator();
function next(err, result) {
if(err){
return fn(err);
}
var step = gen.next(result);
if (!step.done) {
step.value(next);
} else {
fn(null, step.value);
}
}
next();
}
}
用法:
var co = require('./co');
// wrap the function to thunk
function readFile(filename) {
return function(callback) {
require('fs').readFile(filename, 'utf8', callback);
};
}
co(function * () {
var file1 = yield readFile('./file/a.txt');
var file2 = yield readFile('./file/b.txt');
console.log(file1);
console.log(file2);
return 'done';
})(function(err, result) {
console.log(result)
});
会打印出: content in a.txt content in b.txt done
返回一个functoin是为了把一个普通的函数变成thunk thunk类似与promise, 可以把一个函数延后执行,每个thunk函数只有一个参数 这段代码就是将一个普通的nodejs函数转换为thunk:
function readFile(filename) {
return function(callback) {
require('fs').readFile(filename, 'utf8', callback);
};
}
当你调用readFile(‘a.txt’)的时候并不会去读取文件,它会返回一个function,然后通过这个function去执行:
readFile('a.txt')(function(err,result){
});
把普通的函数转为thunk是为了配合co的实现(能够被yield),TJ大神写过一个库可以方便地将普通的nodejs函数转换成thunk(https://github.com/visionmedia/node-thunkify) 这里的co函数返回一个function(fn)是为了把co函数本身也变成一个thunk,这样就可以被yield了
@ltebean 我把co源码里 return function (done) {} 这2行注释了 co也能正常运行,是不是说明return function(){} 一般情况下没什么用? 还有返回的function里面的内容怎么会自动执行的?匿名函数不是应该这样才会执行吗? (function(){ })();
谢谢楼主,我是看着这个代码搞明白co和thunkify的基本原理的。 如果还有人没明白,http://blog.shiqichan.com/using-es6-generators-in-nodejs/ 我写了个日志,又做了下拆解,换了个ping获取mac地址的例子。 希望能帮助到需要的人。
要看懂Co, 建议先将generator的基本特性了解清楚 特别几个东东: gen.next , 特别是带参数的gen.next(args), 还有就是返回值ret.value, ret.done等 gen.throw, 了解try catch如何做到的? yield, yield和gen.next的关系? yield* 和yield的关系?有什么好处?
理解了下这个代码,写了个文章。跟我一样的初学者可以参考 http://www.html-js.com/article/Nodejs-study-notes-to-understand-co-execution-logic