Pipe async steps in sequence
A request pipeline is rarely all synchronous: parse the input, fetch something, validate the response, map it to view state. Some steps return promises and some do not, and they must run in order because each depends on the last — which rules out Promise.all and rules out forEach.
Implement pipeAsync(...fns). It returns an async function that calls the leftmost function with all of the arguments it received, awaits the result, passes that value to the next function, and so on left to right, resolving with the last function's value. Steps run strictly in sequence: a step is not started until the previous one has settled. Steps may be synchronous or asynchronous and are treated identically. If any step throws or returns a rejected promise, the returned promise rejects with that error and no later step is called. With no functions at all, the returned function resolves with its first argument unchanged.
Arguments
...fnsFunction[]- Any mix of sync and async unary functions. The leftmost may take any arity.
Returns
(...args) => Promise<any> — An async function that threads a value through fns left to right, awaiting each step.
Examples
const run = pipeAsync(
(n) => n + 1, // sync
async (n) => { await delay(5); return n * 2; }, // async
(n) => "value:" + n // sync
);
await run(4); // "value:10"Sync and async steps mix freely — await on a non-promise is a no-op.
try {
await pipeAsync(
async () => { throw new Error("stop"); },
() => "never reached"
)(1);
} catch (e) {
// e.message === "stop" — later steps skipped on the first error
}What it has to do
- Thread the value left to right, awaiting each step before starting the next.
- Treat synchronous and promise-returning steps identically.
- Pass every argument to the leftmost step.
- Reject with the first error, whether thrown synchronously or rejected, and skip the remaining steps.
- With no functions, resolve with the first argument unchanged.
Notes
- A plain
forloop withawaitinside anasyncfunction gives you sequencing for free.Promise.allwould run steps in parallel — wrong here. awaiton a non-promise just resolves to the value, so you never need to detect whether a step returned a promise.
Stuck? The javascript course covers everything this challenge needs.
- 1.threads a value through sync and async steps
- 2.runs steps in sequence, never in parallel
- 3.passes every argument to the first step
- 4.rejects on the first failure and skips later steps
- 5.with no steps resolves with the first argument
These assertions run in your browser the moment you hit Run. Pass all of them to claim the XP.
Discussion
Sign in to postNo comments yet. Be the first to say something.