蓝鸟出游用法
Bluebird coroutine usage
我正试图使用Bluebird的协同程序,如下所示:
var p = require('bluebird');
//this should return a promise resolved to value 'v'
var d = p.coroutine(function*(v) { yield p.resolve(v); });
//however this prints 'undefined'
d(1).then(function(v){ console.log(v); });
这里有什么不正确的地方?
引用coroutine
、的文档
返回一个可以使用
yield
生成promise的函数。当生成的promise结算时,控制权将返回给生成器。
因此,函数可以使用yield
,但yield
不用于从函数返回值。使用return
语句从该函数返回的内容将是协程函数的实际解析值。
Promise.coroutine
只是让yield
语句等待promise解析,实际的yield
表达式将被求值为解析的值
在您的情况下,表达式
yield p.resolve(v);
将被计算为1
,并且由于您没有从函数显式返回任何内容,因此默认情况下,JavaScript返回undefined
。这就是为什么结果是undefined
。
为了解决这个问题,你实际上可以返回收益值,比如这个
var p = require('bluebird');
var d = p.coroutine(function* (v) {
return yield p.resolve(v);
});
d(1).then(console.log);
让我们从您的代码开始:)
var d = p.coroutine(function*(v) {
yield p.resolve(v);
});
当你做d(1)时,bluebird的协程会发挥它的魔力,并评估promise函数,即p.resolve(v)。现在,协程的工作方式是调用promise函数然后执行实际的yield,即流在执行产生的promise后返回到实际的生成器。
现在,yield不用于返回值,不像resolve函数,后者可以在promise的情况下用于获取"then"中的值。
因此,不会返回任何值,因此会得到未定义的值。
所以你可以做两件事:
首先简单地显式返回收益率值:
var d = p.coroutine(function* (v) {
return p.resolve(v);
})
这将返回通过执行promise获得的yield中获得的值,因此可以使用then获得值。像
d(7).then((val) => {
console.log(val);
});
但是,如果您有另一个promise函数,该怎么办。例如:
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');
});
那么在这里执行返回操作将不会执行另一个yield函数,即如果您在上面的代码中返回第一个yield值,那么第一个yide之后的代码将不会执行。
因此,我可以做的一件事是处理给定承诺本身的"当时":
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) {
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}