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 200 <Buffer 0d 0a 3c 21 44 4f 43 54 59 50 45 20 68 74 6d 6c 3e 0d 0a 3c 68 74 6d 6c 20 6c 61 6e 67 3d 22 65 6e 22 3e 0d 0a 3c 68 65 61 64 3e 0d 0a 20 20 20 20 3c ... >
188