快来围观co@4的核心源码:
function co(gen){
var ctx=this;
return new Promise(function(resolve,reject){
if(typeof gen === 'function')gen=gen.call(ctx);
if(!gen||typeof gen.next !== 'function')return resolve(gen);
onFulfilled();
function onFulfilled(res){
var ret;
try{
ret=gen.throw(err);
}catch(e){
return reject(e);
}
next(ret);
}
function onRejected(err){
var ret;
try{
ret=gen.throw(err);
}catch(e){
return reject(e);
}
next(ret);
}
function next(ret){
if(ret.done)return resolve(ret.value);
var value=toPromise.call(ctx,ret.value);
if(value && isPromise(value))return value.then(onFulfilled,onRejected);
return onRejected(new TypeError('you may only yield a function,promise,generator,array,or object',+'but the following object was passed: "'+String(ret.value)+'"'));
}
});
}
co将yield后面的表达式全都封装成了Promise对象。Promise(function(resolve,reject)
当前表达式执行结束(即执行promise的then方法)
才会执行fulfilled方法,内部执行gen.next方法。
执行表达式。调用下一个gen.next()。
中间限制了传入参数的数据类型。yield后面只能跟thunk,promise,generator,generatorFunction,array或者object。
return onRejected(new TypeError('you may only yield a function,promise,generator,array,or object',+'but the following object was passed: "'+String(ret.value)+'"'));
1.问题
co把传入参数的上下文改成自己的上下文。
var ctx=this;
...
gen=gen.call(ctx);
所以使用的时候需要bind一个上下文。