r03 r03 - 7 months ago 44
Javascript Question

Run functions that return promises in series after promise is done

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);
});
}

Answer

If each of the functions returns a promise itself, you can just chain them together. Something like this should work:

function runFuncs(funcs) {
  return funcs.reduce(function (p, funcToRun) {
      return p.then(function () {
        return funcToRun();
      });
  }, Promise.resolve(null));
}

Basically, you just keep chaining the promises together. By the nature of the chain, if you return a promise from the then handler, that becomes the resulting promise. So the reduce call goes through each promise in the array, doing a then on it to process the next one in the array.