I want to run a dynamic list of async things in parallel where some of things require other things to be finished first, then have access to all aggregated results. So far I came up with iterating through multidim. array of the operations, but it needs wrapping function/closure so I am not fully happy with it. I'm wondering what else people are doing for this situation.
var runAllOps = function(ops) {
var all = []; // counter for results
var runOperations = function runOperations(ops) {
var set = ops.shift();
return Promise.map(set, function(op){
return op.getData.call(null, op.name)
})
.then(function(results){
all.push(results)
if (ops.length){
return runOperations(ops)
} else {
return _.flatten(all)
}
})
}
return runOperations(ops)
}
The operations looks like this:
var operations = [
[
{name: 'getPixieDust', getData: someAsyncFunction},
{name: 'getMandrake', getData: etc},
],
[
{name: 'makePotion', getData: brewAsync}
]
]
Is there some good way to map dependencies with promises? It would be nice to be able something like:
makePotion: [getPixieDust, getMandrake]
then pass the whole thing off to something which knows getPixieDust and getMandrake are to be finished first before calling makePotion. Instead of current implementation of just puting the dependent operations in the later arrays
There is currently no automatic way to do this in Bluebird or any other promise library I know of. Simply put - you do this by building the tree yourself.
Here is how I deal with this issue. First of all, let's cache results:
var pixieDustP = null;
function getPixieDust(){
return pixieDustP || (pixieDustP = apiCallReturningPromise());
}
var mandrakeP = null;
function getMandrake(){
return mandrakeP || (mandrakeP = apiCallReturningPixieDustPromise());
}
function makePotion(){
return Promise.join(getMandrake(),getPixieDust(),function(dust,mandrake){
// do whatever with both, this is ok since it'll call them both.
// this should also probably be cached.
});
}