Generator 和 yield
es6 有一个 generator 函数,它是一个普通函数,但是有两个特征。一是,function
关键字与函数名之间有一个星号;二是,函数体内部使用yield
语句,定义不同的内部状态
每次执行 generator 函数会返回一个 iterator,在有 yield 的关键字停止,所以每次执行一次 iterator.next 会在下一个 yield 停止,可以通过 next(val) 把结果返回出来
根据这个原理来实现一个简单的 co 函数
function co(gen) { var g = gen(); var next = g.next(); var res = next.value; function _next(next, res) { if (!next.done) { if (res && res.constructor == Promise) { res.then(function (val) { next = g.next(val); res = next.value; _next(next, res); }); } else if (res.constructor == Function) { var fn = res; fn(function (err, res) { next = g.next(res); res = next.value; _next(next, res); }); } else { next = g.next(res); res = next.value; _next(next, res); } } } _next(next, res);}
测试一下~
var fs = require("fs");var readThunk = thunkify(fs.readFile);co(function * gen() { var pro = new Promise(function(resolve, reject) { resolve(1999); }); var r3= yield pro; var r1 = yield 100; var r2 = yield 200; var a = yield readThunk("./a.html"); var c = yield function (fn) { setTimeout(function() { fn(null, 188); }, 1000) } console.log(r3, r1, r2, a); console.log(c);})// 结果1999 100 200188