Javascript 蓝知更鸟协同程序使用
我尝试使用蓝鸟的协同程序,如下所示:Javascript 蓝知更鸟协同程序使用,javascript,node.js,promise,bluebird,coroutine,Javascript,Node.js,Promise,Bluebird,Coroutine,我尝试使用蓝鸟的协同程序,如下所示: var p=require('bluebird'); //这应返回解析为值“v”的承诺 var d=p.coroutine(函数*(v){yield p.resolve(v);}); //但是,这会打印“未定义” 然后(函数(v){console.log(v);}); 这里有什么不正确的地方?引用 返回可以使用yield生成承诺的函数。当问题解决后,控制权将返回到生成器 因此,函数可以使用yield,但yield不用于从函数返回值。使用return语句从该
var p=require('bluebird');
//这应返回解析为值“v”的承诺
var d=p.coroutine(函数*(v){yield p.resolve(v);});
//但是,这会打印“未定义”
然后(函数(v){console.log(v);});
这里有什么不正确的地方?引用
返回可以使用yield
生成承诺的函数。当问题解决后,控制权将返回到生成器
因此,函数可以使用yield
,但yield
不用于从函数返回值。使用return
语句从该函数返回的任何内容都将是协程函数的实际解析值
Promise.coroutine
只是让yield
语句等待Promise解析,实际的yield
表达式将计算为解析值。
在你的例子中,表达式
yield p.resolve(v);
将被计算为1
,并且由于您没有显式地从函数返回任何内容,因此默认情况下,JavaScript返回未定义的
。这就是结果是未定义的原因
要解决这个问题,您可以实际返回生成的值,如下所示
var p = require('bluebird');
var d = p.coroutine(function* (v) {
return yield p.resolve(v);
});
d(1).then(console.log);
让我们从您的代码开始:)
当您执行d(1)时,蓝鸟的协同程序执行它的神奇操作,并评估承诺函数,即p.resolve(v)。现在,协同程序的工作原理是调用promise函数,然后执行实际收益率,即流在执行收益率承诺后返回到实际生成器
现在,收益率不用于返回值,这与resolve函数不同,resolve函数可用于在承诺的情况下获取“then”中的值
因此不返回任何值,因此未定义
所以你可以做两件事:
首先,只需显式返回收益率值:
var d = p.coroutine(function* (v) {
return p.resolve(v);
})
这将返回通过履行承诺获得的“收益”中获得的价值,因此可以使用“then”获得价值。
像
但是,如果你有另一个,承诺函数来屈服呢。i、 例如:
var d = bluebird.coroutine(function* (val) {
yield bluebird.resolve(val);
console.log('i am here');
yield(bluebird.resolve('here' + val));
console.log('i am at the last');
});
那么在这里执行返回操作将不会执行另一个屈服函数,也就是说,如果在上述代码中以第一个屈服值返回,那么在第一个屈服值之后的代码将不会执行
因此,我能做的一件事是处理给定承诺的“然后”,就像:
var d = bluebird.coroutine(function* (val) {
yield bluebird.resolve(val).then(function(data) {
// process data here
console.log(data);
});
});
d(4).then(() => {
console.log('done execution');
});
这一点,你可以做任何承诺。
以下是演示代码:
var bluebird = require('bluebird');
bluebird.coroutine(function *temp() {
console.log('starting');
yield(new Promise((resolve, reject) => {
setTimeout(function() {
return resolve('first yield data');
}, 2000);
}).then((data)=>{console.log(data)}));
yield(new Promise((resolve, reject) => {
setTimeout(function() {
resolve('second yield data');
}, 3000);
}).then((data) => {console.log(data)}));
})().then(() => {
console.log('finally done');
});
通过这种方式,您可以在bluebird中产生尽可能多的承诺,并在各自的“then”中获得它们解析的值,并处理解析的数据。function co(gen){
function co(gen) {
const it = gen(), next = it.next.bind(it), raise = it.throw.bind(it);
return () => new Promise((resolve, reject) => {
const factory = (fn) => (data) => {
try {
const {value, done} = fn(data);
if (done) {
resolve(value);
} else {
Promise.resolve(value).then(factory(next), factory(raise));
}
} catch(reason) {
reject(reason);
}
};
factory(next)();
});
}
const example = co(function*() {
// const x = yield Promise.reject(12);
const x = yield Promise.resolve(12);
return x
// throw x
});
example(); // Promise {<resolved>: 12}
const it=gen(),next=it.next.bind(it),raise=it.throw.bind(it);
return()=>新承诺((解决、拒绝)=>{
常数工厂=(fn)=>(数据)=>{
试一试{
const{value,done}=fn(数据);
如果(完成){
决心(价值);
}否则{
承诺。解决(价值)。然后(工厂(下一个),工厂(提高));
}
}捕获(原因){
拒绝(理由);
}
};
工厂(下一期)();
});
}
常量示例=co(函数*(){
//常数x=屈服承诺。拒绝(12);
const x=收益承诺。解决(12);
返回x
//掷x
});
示例();//承诺{:12}
所以,我也可以做一个p.coroutine(function*(){yield d(1);})
对吗?@pkyeck在你的例子中d
是什么?你在示例代码中创建的coroutine通常只回答没有用。
var bluebird = require('bluebird');
bluebird.coroutine(function *temp() {
console.log('starting');
yield(new Promise((resolve, reject) => {
setTimeout(function() {
return resolve('first yield data');
}, 2000);
}).then((data)=>{console.log(data)}));
yield(new Promise((resolve, reject) => {
setTimeout(function() {
resolve('second yield data');
}, 3000);
}).then((data) => {console.log(data)}));
})().then(() => {
console.log('finally done');
});
function co(gen) {
const it = gen(), next = it.next.bind(it), raise = it.throw.bind(it);
return () => new Promise((resolve, reject) => {
const factory = (fn) => (data) => {
try {
const {value, done} = fn(data);
if (done) {
resolve(value);
} else {
Promise.resolve(value).then(factory(next), factory(raise));
}
} catch(reason) {
reject(reason);
}
};
factory(next)();
});
}
const example = co(function*() {
// const x = yield Promise.reject(12);
const x = yield Promise.resolve(12);
return x
// throw x
});
example(); // Promise {<resolved>: 12}