Bluebird: Promise.reduce skips first array element.

Created on 18 Feb 2015  路  15Comments  路  Source: petkaantonov/bluebird

http://jsfiddle.net/RichAyotte/t0rjhrab/

var pets = ['cat', 'dog', 'bird'];
Promise.reduce(pets, function(_, p) {
    console.log(p);   
});

Log

dog
bird

Most helpful comment

that is expected behavior. your 0th argument is being used as the initial value for the reduce

http://jsfiddle.net/cantremember/766up1an/

var pets = ['cat', 'dog', 'bird'];
Promise.reduce(pets, function(_, p) {
    console.log(p);
    return _ + ',' + p;
}).then(function(_) {
    console.log('=', _); // => 'cat,dog,bird'
});

whereas pass a 3rd argument, such as 'mouse' to Promise#reduce and you'll see each element of your Array being visited

All 15 comments

that is expected behavior. your 0th argument is being used as the initial value for the reduce

http://jsfiddle.net/cantremember/766up1an/

var pets = ['cat', 'dog', 'bird'];
Promise.reduce(pets, function(_, p) {
    console.log(p);
    return _ + ',' + p;
}).then(function(_) {
    console.log('=', _); // => 'cat,dog,bird'
});

whereas pass a 3rd argument, such as 'mouse' to Promise#reduce and you'll see each element of your Array being visited

Thanks, what @cantremember said is correct. This is just like Array#reduce

Ah yes, thanks. Even null works.

Promise.reduce(pets, function(_, p) {
 console.log(p);   
}, null);

Are you sure you should even be using reduce?

I'm building a promise chain from an array. Is there a simpler way or convenience function for this?

    return Promise.reduce(classes, function(_, c){
        return drop(c).then(function(){
            console.log(c + ' dropped');
        });
    }, null);

Something like this would be nice. Like map but chain instead.

Promise.chain(Array, Function) -> Promise

@RichAyotte could be wrong but it sounds like you're running into this issue: https://github.com/petkaantonov/bluebird/issues/134

@phpnode Nice thread, thanks. It's exactly what I was looking for. I've got lots of options now between reduce, each and map. Figuring out which one is the most expressive for the task at hand is the challenge now :)

return Promise.each(classes, function(c) {
        return drop(c).then(function(){
            console.log(c + ' dropped');
        });
});

@petkaantonov Yep, that's the one that I went for. :+1:

@RichAyotte FYI if this actually happens to be related to oriento then it's FIFO anyway, so you can probably just:

return Promise.map(classes, drop)

@phpnode It is :)

exports.down = function (db) {
    return Promise.each([
        'InstitutionClass'
        , 'Establishment'
        , 'EstablishmentType'
        , 'Address'
        , 'AddressUnitDesignator'
        , 'AddressStreetType'
        , 'AddressStreeDirection'
        , 'AddressCivicNumberSuffix'
        , 'Region'
        , 'RegionType'
        , 'OrderItem'
        , 'Order'
        , 'Meal'
        , 'Drink'
        , 'contains'
        , 'FoodIngredient'
        , 'Food'
        , 'FoodType'
        , 'Person'
        , 'Obj'
    ], db.class.drop);
};

the API.md doesn't state otherwise, but #each executes its Promises in parallel, much like #all, correct?

nope, its sequential

thanks, good to know. i must have overlooked that

Was this page helpful?
0 / 5 - 0 ratings