我正试图弄清楚如何通过yield
获取承诺的价值,可能还有“co”:
function *(){
var someVar = yield functionThatReturnsAPromise();
}
被调用的函数不是生成器,只是普通函数。使用上面的someVar == Promise
,但我想要解析的值。 co或其他图书馆有办法做到这一点吗?
答案 0 :(得分:7)
是的, co </ strong>可以做到这一点。你必须在co
调用中包装父函数:
co(function *(){
var someVar = yield functionThatReturnsAPromise();
})()
内部的 someVar
将成为解决价值。如果承诺被拒绝,则可以使用基本的try {} catch (e) {}
语句进行错误。
答案 1 :(得分:7)
通常,yield act会返回与其自己的暂停执行(yield函数的左侧)相同的值,而不是生成器的调用函数。在这个简单的例子中,从1到5的例子计算,yield的输入是生成器函数的yield的输出以及生成器的执行路径:
function* inc() {
var g = 0;
while (true) {
g = yield g + 1;
}
}
var incGen = inc();
for (i = incGen.next().value; i <= 5; i = incGen.next(i).value) {
console.log(i); // ^ input of generator is last output
}
但是,调用函数也可以调用生成器,但是将输出的最后一个yield替换为另一个值,或者甚至为生成器的执行抛出异常。在promise的情况下,返回promise的函数可能会产生该promise的结果而不是promise本身。所以在这种情况下:
var someVar = yield functionThatReturnsAPromise();
^ output != ^ input
您希望yield作为一个函数,将promise作为输入,并将已解析的promise作为输出返回给生成器函数。
恰好co
能够为你做到这一点。您需要做的就是将生成器函数提供给co
函数:
co(function *(){
var someVar = yield functionThatReturnsAPromise();
})
为了更好地理解这是如何工作的,这里是一个函数的例子,与co做同样的事情:
function async(makeGenerator){
return function (){
var generator = makeGenerator.apply(this, arguments)
function handle(result){
if (result.done) return result.value
return result.value.then(function (res){
return handle(generator.next(res)) // <- sets output of yield to the promise result
}, function (err){ // and returns input promise
return handle(generator.throw(err)) // <- throw promise exception to generator function
})
}
return handle(generator.next()) // <- first time call, input of yield is a promise
}
}
source is from Forbes Lindesay's now famous presentation about this concept