FrontendPro

44Implement asyncReduce() with sequential execution

mediumAbout 35 minutesCodingpromisesasyncarrays

Problem

Implement asyncReduce(items, reducer, initialValue). It works like Array.prototype.reduce, but the reducer(accumulator, item, index) may be async, and each call starts only after the previous one has finished, because each step needs the previous result.

// Apply database migrations one after another.
const version = await asyncReduce(migrations, async (current, migration) => {
  await migration.run();
  return migration.version;
}, 0);

Requirements

  • Run the reducer calls strictly one at a time, in order.
  • Items may themselves be promises; await each item before passing it on.
  • Without an initial value, the first item is the starting accumulator. With an empty input and no initial value, reject with a TypeError.
  • An explicit initialValue of undefined still counts as given.
  • If a call rejects, reject and do not call the reducer again.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

solution.jsJavaScript

Press Run or ⌘ Enter to execute your code.

Step-by-step

Use a rest parameter, ...initial, and check initial.length, so asyncReduce(items, fn, undefined) is treated as "initial value given", like the built-in reduce.

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 4 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever