Phoelpis Phoelpis - 21 days ago 7
Javascript Question

Chaining promises but continue with the next promise when one fails (and log the rejection)

I have a number of functions stored in an array.
Basically I have two questions.


  1. How to turn this array of functions into chained promises. (a long array)
    Something in the lines of:
    funcs.reduce((prev, cur) => prev.then(cur), starting_promise);


    or

    var promise = funcs[0](input);
    for (var i = 1; i < funcs.length; i++) promise = promise.then(funcs[i]);

  2. (this is the main question) Will like the promise chain not to reject when one of the promises in chain rejects. But instead to continue withe the next one, until it reaches the last. (if possible also catching the rejection, so i can output what went wrong)


Answer

You can handle the rejection within the reduce callback;

funcs.reduce((prev, cur) => prev.then(cur).catch(log), starting_promise)

Or you could pre-process the array of functions:

funcs.map(f => v => f(v).catch(log)) 
  .reduce((prev, cur) => prev.then(cur), starting_promise)

In either case, the point is that the catch puts the promise back on the success track, as it were (unless you throw inside the catch handler).

Note that whatever the catch handler returns becomes the input value to the next function in the promise chain. If you want the rejection reason to become the input, then return it from the catch handler:

function log(reason) {
  console.log("rejected with reason", reason, "continuing...");
  return reason;
}

From a comment:

How do I use the cur reference in the catch -> log function?

Instead of just passing log to the catch, pass a function which calls log with both the reason and the function:

funcs.reduce(
  (prev, cur) => prev.then(cur).catch(reason => log(reason, cur)), 
  starting_promise)

function log(reason, func) {
  console.log("rejected with reason", reason, "in function", func, "continuing...");
  return reason;
}