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

Contributing "waitFor" function to async module, desired? #6213

Open
acrodrig opened this issue Nov 26, 2024 · 1 comment
Open

Contributing "waitFor" function to async module, desired? #6213

acrodrig opened this issue Nov 26, 2024 · 1 comment

Comments

@acrodrig
Copy link

Very often when writing integration tests I need to wait for a condition to be true to continue (for example the database record is there, or an SMS message has arrived). I use the function below repeatedly and I would love if it can be part of @std/async. If you see value in it, would contribute as PR. Please let know.

/**
 * Wait for a condition to be true, jumping every `jump` milliseconds until 
 * `timeout` is reached. Can be used as:
 *
 * ```typescript
 * let i = 0;
 * const id = setInterval(() => i++, 42);
 * await waitFor(() => i > 10);
 * clearInterval(id);
 * assert(i > 10);
 * ```
 *
 * @param condition - predicate returning a (potentially promised) boolean
 * @param timeout - maximum wait time (default 20s, 0 for infinite)
 * @param jump - the time to wait between checks (default 100ms)
 */
function waitFor(condition: () => boolean | Promise<boolean>, timeout = 20000, jump = 100) {
  // Time we start the checks so that we can
  const start = Date.now();

  return new Promise(function (resolve, reject) {
    // If condition is "truthy" resolve, if timeout reject, otherwise keep waiting
    const check = async function (): Promise<void> {
      const value = await condition();
      if (value) return resolve(value);
      const time = Date.now() - start;
      if (time > timeout) return reject(new Error("Timeout (" + timeout + "ms) waiting for condition!"));
      setTimeout(check, jump);
    };

    // Start checking
    setTimeout(check);
  });
}
@kt3k
Copy link
Member

kt3k commented Nov 28, 2024

The suggestion looks reasonable to me.

Please add this as unstable feature first. https://github.com/denoland/std/blob/9daae0547ff646dddcd0628afe355b61eace78d5/.github/CONTRIBUTING.md#suggesting-a-new-feature

The error class might better to be DOMException with TimeoutError name, that is what AbortSignal.timeout() and @std/async/deadline throw

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