It's the first time I use reduce with promise, and it's look perfect for my usage.

However, I'm trying to use reduce to iterate more than the original size of my array (call reduce_array in my example).

In fact, in this example, methodThatReturnsAPromise worth true in certain case, false in other. (in the end it always finish by worth false)

The idea is if results is false then reduce work normaly, and go to the next value (nextId). In the other hand, if results is true, I have to resolve methodThatReturnsAPromise with the same value again.

I already try differents methods using the index in parameter, or I already try to push again the id in reduce_array but none of that work.

    reduce_array.reduce((accumulatorPromise, nextId, index, array) => {
        return accumulatorPromise.then((results) => {
            //if results === end || result === unknownDomain
            //next

            //first iteration, results don't exist
            if (results) {
                if (results === true) {
                    index++;
                    return methodThatReturnsAPromise(nextId - 1);
                } else {
                    return methodThatReturnsAPromise(nextId);
                }
            } else {
                return methodThatReturnsAPromise(nextId);
            }

        })
    }, Promise.resolve());

1 Answers

2
CertainPerformance On Best Solutions

A do/while loop inside a for loop will probably be a lot simpler:

(async () => {
  for (const nextId of reduce_array) {
    let result;
    do {
      result = await methodThatReturnsAPromise(nextId);
    } while (result !== true);
  }
})();

If you had to use reduce, you could put a named function which calls itself recursively inside the reduce callback:

reduce_array.reduce((accumulatorPromise, nextId) => {
  return accumulatorPromise.then(() => {
    const getThisInfo = () => methodThatReturnsAPromise(nextId)
      .then((result) => (
        result === true
          ? getThisInfo()
          : null
      ));
    return getThisInfo();
  })
}, Promise.resolve());

Which is a bit ugly and not so easy to read. I'd prefer the for loop.