CNode

co最简版实现,学习generator & co

精华
分享
Lltebean发布于12 年前最后回复11 年前13 回复33978 浏览0 收藏

看了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

查看回复

回复 (13)

K
kylezhang#1·11 年前

mark

J
JingYongWang#2·11 年前
引用 LastKing博主 还能回答问题不?为什么我运行项目 Debugger listening on port 18507 f:\nodejs\node study\generator\Test4.js:27 ...

@LastKing 可能是因為你用的Node版本是4.0以上, 你去co的原始碼看,我沒有研究先改成這樣寫是OK的, https://github.com/tj/co 把下面這段

(function(err, result) { console.log(result) });

改寫成下面這樣應該就OK了!

.then(function (result){ console.log(result); }, function(err){ console.log(err); });

P
Pana#3·12 年前

好东西, 这样许多人学习起来会省很多力气

H
hackerjs#4·12 年前

不错,有货。

F
fengmk2#5·12 年前

赞,可以继续写续篇,说说try catch是如何做到的。

A
a379395979#6·12 年前

return function(fn) {} ,看的不是很懂,返回一个函数有什么用? 好心的lz可以解释下吗?

L
ltebean#7·12 年前
引用 a379395979return function(fn) {} ,看的不是很懂,返回一个函数有什么用? 好心的lz可以解释下吗?

返回一个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了

A
a379395979#8·12 年前
引用 a379395979return function(fn) {} ,看的不是很懂,返回一个函数有什么用? 好心的lz可以解释下吗?

@ltebean 我把co源码里 return function (done) {} 这2行注释了 co也能正常运行,是不是说明return function(){} 一般情况下没什么用? 还有返回的function里面的内容怎么会自动执行的?匿名函数不是应该这样才会执行吗? (function(){ })();

B
blacktail#9·12 年前

要看懂Co, 建议先将generator的基本特性了解清楚 特别几个东东: gen.next , 特别是带参数的gen.next(args), 还有就是返回值ret.value, ret.done等 gen.throw, 了解try catch如何做到的? yield, yield和gen.next的关系? yield* 和yield的关系?有什么好处?

J
JasmineYuan#10·12 年前

理解了下这个代码,写了个文章。跟我一样的初学者可以参考 http://www.html-js.com/article/Nodejs-study-notes-to-understand-co-execution-logic

M
MarshalW#11·12 年前

谢谢楼主,我是看着这个代码搞明白co和thunkify的基本原理的。 如果还有人没明白,http://blog.shiqichan.com/using-es6-generators-in-nodejs/ 我写了个日志,又做了下拆解,换了个ping获取mac地址的例子。 希望能帮助到需要的人。

L
LastKing#12·11 年前

博主 还能回答问题不?为什么我运行项目 Debugger listening on port 18507 f:\nodejs\node-study\generator\Test4.js:27 })(function(err,result){ ^ TypeError: object is not a function

W
wewea#13·11 年前

太好了, 太有参考价值了.

参与回复
登录后即可参与回复。登录