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 is 0, it's like the each is not being finished before the last then is being fired?
If ReturnsService.getTotalAmount() is asynchronous, Bluebird's .each() won't wait for that to complete its work and for totalAmount to be modified without some guidance:
If the iterator function returns a promise or a thenable, then the result of the promise is awaited, before continuing with next iteration.
If getTotalAmount() provides a promise itself, a return is all that needs to be added:
.each(function (returns){
return ReturnsService.getTotalAmount(returns.products, ...);
})
Otherwise, a new Promise() should be created for it:
.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 as aside, the scenario of iterating to determine a single value (sum total, 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 });
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With