Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bluebird promises - how to explode an array, then map it?

If I have an array:

['one.html','two.html','three.html']

how could I explode that array, apply a chain of promises to it, then combine it back together again? At the moment my code is like this:

Promise.map(['one','two','three'], function(i) {
    dbQuery('SELECT ' + i);
}).then(function(results) {
    // This has an array of DB query results
});

I'm imagining something like:

Promise.map(['one','two','three'], function(i) {
    dbQuery('SELECT ' + i);
})
.explode()
.then(function(result) {
    // Individual result
})
.combine()
.then(function(results) {
    // Now they're back as an array
});

Now, I know Bluebird doesn't have these functions, so I'm wondering what the correct Promise-y way is of doing this?

like image 953
Alastair Avatar asked Jun 02 '14 01:06

Alastair


2 Answers

You can use a chain of maps:

Promise.map(['one','two','three'], function(i) {
    return dbQuery('SELECT ' + i);
}).map(function(result) {
    // Individual result
}).map(function(result) {
    // Individual result
}).map(function(result) {
    // Individual result
}).then(function(results) {
    // Now they're back as an array
});

However the above will not be as concurrent as

Promise.map(['one','two','three'], function(i) {
    return dbQuery('SELECT ' + i).then(function(result) {
        // Individual result
    }).then(function(result) {
        // Individual result
    }).then(function(result) {
        // Individual result
    })
}).then(function(results) {
    // Now they're back as an array
});
like image 117
Esailija Avatar answered Sep 20 '22 12:09

Esailija


Bluebird does in fact have this. but it doesn't modify the array: Promise.each()

var transformed = []

Promise.map(['one','two','three'], function(i) {
    return dbQuery('SELECT ' + i);
})
.each(function(result) {
    // This is repeating access for each result
    transformed.push(transformResults(result));
})
.then(function(results) {
    // here 'results' is unmodified results from the dbQuery
    // array doesn't get updated by 'each' function
    // here 'transformed' will contain what you did to each above
    return transformed
});

Chaining maps or adding more promises off dbQuery works well, but each() could be advantage if you only want a side effect when touching individual results

like image 25
aarosil Avatar answered Sep 21 '22 12:09

aarosil