forked from denoland/std
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunstable_wait_for.ts
63 lines (58 loc) · 1.88 KB
/
unstable_wait_for.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import { deadline } from "./deadline.ts";
/** Options for {@linkcode waitFor}. */
export interface WaitForOptions {
/** Signal used to abort the waitFor. */
signal?: AbortSignal;
/** Indicates the step jump in time to wait for the predicate to be true.
*
* @default {100}
*/
step?: number;
}
/**
* Resolve a {@linkcode Promise} after a given predicate becomes true or the
* timeout amount of milliseconds ahs been reached.
*
* @throws {DOMException} If signal is aborted before either the waitFor
* predicate is true or the timeout duration was reached, and `signal.reason`
* is undefined.
* @param predicate a Nullary (no arguments) function returning a boolean
* @param ms Duration in milliseconds for how long the waitFor should last.
* @param options Additional options.
*
* @example Basic usage
* ```ts no-assert
* import { waitFor } from "@std/async/unstable-wait-for";
*
* // Deno server to acknowledge reception of request/webhook
* let requestReceived = false;
* Deno.serve((_req) => {
* requestReceived = true;
* return new Response("Hello, world");
* });
*
* // ...
* waitFor(() => requestReceived, 10000);
* // If less than 10 seconds pass, the requestReceived flag will be true
* // assert(requestReceived);
* // ...
* ```
*/
export function waitFor(
predicate: () => boolean | Promise<boolean>,
ms: number,
options: WaitForOptions = {},
): Promise<void> {
const { step = 100 } = options;
// Create a new promise that resolves when the predicate is true
let interval: number;
const p: Promise<void> = new Promise(function (resolve) {
interval = setInterval(() => {
if (predicate()) resolve();
}, step);
});
// Return a deadline promise
return deadline(p, ms, options).finally(() => clearInterval(interval));
}