Flow control with a promise
I have this piece of code:
var totalAmount = 0;
Returns.find().populate("products")
.then(function (returns){
return returns;
})
.each(function (returns){
ReturnsService.getTotalAmount(returns.products, function(err, result){
totalAmount = totalAmount + result;
});
})
.then(function (){
return res.send({total : totalAmount});
});
Why is the result of this code 0, it, like every one, does not end before the last one is run?
source to share
If it ReturnsService.getTotalAmount()
is asynchronous, Bluebird .each()
will not wait for the completion of this work, but for totalAmount
- is modified without any indication:
If the iterator function returns a promise, or whatever is possible, then the result of the promise is expected before continuing with the next iteration.
If getTotalAmount()
the promise itself provides, everything return
needs to be added:
.each(function (returns){
return ReturnsService.getTotalAmount(returns.products, ...);
})
Otherwise, you need to create for it new Promise()
:
.each(function (returns) {
return new Promise(function (resolve, reject) {
ReturnsService.getTotalAmount(returns.products, function(err, result){
if (err)
return reject(err);
totalAmount = totalAmount + result;
resolve(totalAmount);
});
});
})
As an aside, the iteration script to determine one value (sum, etc.) is the intent of another method - .reduce()
.
.reduce(function (runningTotal, returns) {
return new Promise(function (resolve, reject) {
ReturnsService.getTotalAmount(returns.products, function(err, result){
if (err)
return reject(err);
resolve(runningTotal + result); // resolve with new total
});
});
}, 0 /* initial value */)
// combined total will be passed as the argument
.then(function (totalAmount) {
return res.send({ total : totalAmount });
});
source to share