I have an array of functions that I need to execute. Those functions all return a promise.
I want to run all the functions in series, but the next function can only be started if the promise of the previous function is done.
I thought this would be easy with the async or bluebird library, but I can't find a simple solution to this.
Here is something I made (untested), but I was looking for a standard library solution because this probably already exists?
function runFuncs(funcs) {
function funcRunner(funcs, resolve, reject, pos=0) {
funcs[pos]().then(function() {
pos++;
if (pos < length(funcs)) {
funcRunner(funcs, pos);
} else {
resolve();
}
}).catch(function(err) {
reject(err);
});
}
return new Promise(function(resolve, reject) {
funcRunner(funcs, resolve, reject);
});
}
I know you've marked an answer already, but I can't comment yet and had to ask: Your example doesn't seem to pass results from one function to another, do you really need them to run in series?
If series is a hard requirement, Bluebird's .mapSeries()
method will do exactly what you're looking for, and the code is incredibly neat. Otherwise you can swap in .map()
and leverage concurrency to get things done in parallel.
Promise.mapSeries(fnArray, (fn) =>
{
return fn(...);
})
.then((results) =>
{
// do something with the results.
});
Or in parallel with .map()
:
Promise.map(fnArray, (fn) =>
{
return fn(...);
},
{ concurrency: 5 })
.then((results) =>
{
// do something with the results.
});