Open sebiglesias opened 1 month ago
ha! great minds think alike. I wrote this a few days ago:
/**
* Run a list of functions sequentially and return immediately when the
* first error is generated.
* If no errors are found, return a list of result values in the same order.
*/
export function runInSequence<T, E>(
fns: ReadonlyArray<() => ResultAsync<T, E>>,
): ResultAsync<Array<T>, E> {
const run = async () => {
const okValues: Array<T> = [];
for (const fn of fns) {
const result = await fn();
if (result.isErr()) {
return err(result.error);
}
okValues.push(result.value);
}
return ok(okValues);
};
return new ResultAsync(run());
}
One of our use cases of
ResultAsync.combine
is to act as aPromise.all
for several external API calls, which is great for combining multiple ResultAsyncs running in parallel.The array of these
() => ResultAsync<T,E>
can become quite large, so for some scenarios a sequential approach proved to solve some rate-limiting issues.I would imagine there are other scenarios where sequentially running an array of functions returning ResultAsyncs could be useful, such as:
It can also be used as a way to prevent error propagation, if none can fail, as soon as one does no additional calls are made.
The code for this could resemble something like:
@pyrho came up with this.