Trying to understand Javascript generators and promises, I've checked they are good allies. I need to iterate through a coroutine of promises (Promise.coroutine
from Bluebird library) makes easy to execute some promises in the right order. With this code (sorry for the deferred anti-pattern, I'll learn to avoid it later):
function myPromise(x,time,i){
var deferred = Q.defer();
setTimeout(() => {
deferred.resolve(x + i);
},time);
return deferred.promise;
}
router.get('/', function(req, res, next) {
for (var i = 0; i < 5; i++) {
Promise.coroutine(function*(i) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
})(i)
.then(() => {
console.log('Then');
}).
catch((err) => next(err));
}
});
The output in console is (almost) right:
a0 b0
a1 b1
a2 b2
Then
Then
Then
a3 b3
a4 b4
Then
Then
Checking this, my for loop seems to be not good because some promises are ending before the others because of the Then
.
If I include if(i == 3) deferred.reject(new Error(' ERROR!!'));
in the promise, the error is thrown just for that promise and not for the others and it is thrown after the other promises:
ERROR!!
a0 b0
Then
a1 b1
a2 b2
Then
Then
a4 b4
Then
I think iterating with a for loop is not going to be never the solution for this kind of problems. Researching a little bit more, I've tried to use Promise.all
with an array of calls to Promise.coroutine
:
Promise
.all([
Promise.coroutine(1),
Promise.coroutine(2),
Promise.coroutine(3)
])
.then(() => {
console.log('then');
})
.catch((err) => next(err));
But in this case, I take the error:
generatorFunction must be a function
If I do:
var coroutine = function* coroutine(i) {
var a = yield myPromise('a',6000,i);
var b = yield myPromise('b',1000,i);
console.log(a,b);
};
The same generatorFunction must be a function persists.
Do you know what's wrong in here or if there's a better way to "iterate" than Promise.all
?