Bluebird: getting the results of each()

2019-07-23 17:09发布

问题:

Here's something I don't understand about .each(). The function returns a promise that yields the original array instead of an array of results from the callback. How you get the results then? .map() isn't what I'm looking for since the elements need to be processed in order.

var input = [1, 2, 3];
return promise.each(input, causeSideEffect).then(function() {
    /* return true if any side effect occurred */
});

In the example, causeSideEffect() returns a promise of a boolean, indicating whether it did anything.

EDIT: A shim that yield the version 3.0 behavior

var promise = require('bluebird');

var testInput = [ 1 ];
promise.each(testInput, function(){}).then(function(results) {
    if (results[0] === 1) {
        var originalFunction = promise.each;
        promise.each = function(array, callback) {
            var results = [];
            var closure = function(item, index, length) {
                return promise.resolve(callback(item, index, length)).then(results.push.bind(results));
            };
            return originalFunction(array, closure).return(results);
        }
    }
});

回答1:

We agree with you. In fact we agree with you so much that this behaviour changes in 3.0 (where 3.0 will return the modified array).

Basically, .each was not anticipated to be used this way - it was expected that people will use .each only for side effects and not for things they'd use .map for.

Until then, you can either do the accumulation yourself:

var input = [1, 2, 3], result = [];
return promise.each(input, causeSideEffect).then(function() {
    result.push(modificationHappened); // true or false
}).then(function(){
    // access result
}); 

Or use .reduce and accumulate the result into an array (Example in the docs).