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?

+3


source to share


1 answer


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 });
});

      

+4


source







All Articles