Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Sequential ResultAsync combine #592

Open
sebiglesias opened this issue Oct 9, 2024 · 1 comment
Open

[Feature Request] Sequential ResultAsync combine #592

sebiglesias opened this issue Oct 9, 2024 · 1 comment

Comments

@sebiglesias
Copy link

One of our use cases of ResultAsync.combine is to act as a Promise.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:

  • Having certain dependencies between each task/function, or where the outcome of one affects the other.
  • A primitive way of Rate Limiting/Throttling
  • In non idempotent operations, order of each task is important and running them sequentially would be a must. (Specially on longer chains)
  • Batch processing

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:

static combineSequential<T, E>(
  promFuncs: Array<() => ResultAsync<T, E>>
): ResultAsync<T[], E> {
  return promFuncs.reduce(
    (p, c) =>
      p.andThen((acc) => {
        return c().map((v) => {
          acc.push(v);
          return acc;
        });
      }),
    okAsync<T[], E>([] as T[])
  );
}

@pyrho came up with this.

@macksal
Copy link
Contributor

macksal commented Oct 18, 2024

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());
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants