'Getting a promise's value via yield & co
I'm trying to figure out how to get the value of a promise via yield
, possibly with "co":
function *(){
var someVar = yield functionThatReturnsAPromise();
}
The called function is not a generator, just a normal function. With the above, someVar == Promise
, but I want the resolved value. Does co or some other library have a way of doing this?
Solution 1:[1]
Yes, co (https://github.com/tj/co) can do that. You'll have to wrap parent function inside co
call:
co(function *(){
var someVar = yield functionThatReturnsAPromise();
})()
someVar
inside will become resolved value. If promise gets rejected, error can be cought with basic try {} catch (e) {}
statements.
Solution 2:[2]
Typically a yield acts returns the same value to its own paused execution (left hand side of the yield function) as to the calling function of the generator. In this simple example counting from 1 to 5 example the input of the yield is the output of the yield to the generator function as well as to the generator's execution path:
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
}
However, the calling function may also call the generator, but replace the output the last yield with another value or even throw an exception to the generator's execution. In the case of promise a function that returns a promise, may yield the result of that promise instead of the promise itself. So in this case:
var someVar = yield functionThatReturnsAPromise();
^ output != ^ input
you want the yield to act as a function that takes a promise as an input and returns a resolved promise as an output to the generator function.
It so happens co
is able to do exactly this for you. All you need to do is feed your generator function to the co
function:
co(function *(){
var someVar = yield functionThatReturnsAPromise();
})
To better understand how this works, here is an example of a function, that does the same thing as 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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |