From bf5047745bef17e5c325d2d4931305bbd3cc135b Mon Sep 17 00:00:00 2001 From: Alisue Date: Tue, 20 Aug 2024 23:40:11 +0900 Subject: [PATCH 1/7] feat(flushPromises): add `flushPromises` function --- deno.jsonc | 2 ++ flush_promises.ts | 25 +++++++++++++++++++++++++ flush_promises_test.ts | 18 ++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 flush_promises.ts create mode 100644 flush_promises_test.ts diff --git a/deno.jsonc b/deno.jsonc index 2d12f52..9aa9e66 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -6,6 +6,7 @@ "./async-value": "./async_value.ts", "./barrier": "./barrier.ts", "./ensure-promise": "./ensure_promise.ts", + "./flush-promises": "./flush_promises.ts", "./lock": "./lock.ts", "./mutex": "./mutex.ts", "./notify": "./notify.ts", @@ -36,6 +37,7 @@ "@core/asyncutil/async-value": "./async_value.ts", "@core/asyncutil/barrier": "./barrier.ts", "@core/asyncutil/ensure-promise": "./ensure_promise.ts", + "@core/asyncutil/flush-promises": "./flush_promises.ts", "@core/asyncutil/lock": "./lock.ts", "@core/asyncutil/mutex": "./mutex.ts", "@core/asyncutil/notify": "./notify.ts", diff --git a/flush_promises.ts b/flush_promises.ts new file mode 100644 index 0000000..6fb70f2 --- /dev/null +++ b/flush_promises.ts @@ -0,0 +1,25 @@ +/** + * Flush all pending promises in the microtask queue. + * + * ```ts + * import { flushPromises } from "@core/asyncutil/flush-promises"; + * + * let count = 0; + * Array.from({ length: 5 }).forEach(() => { + * Promise.resolve() + * .then(() => count++) + * .then(() => count++); + * }); + * + * console.log(count); // 0 + * await flushPromises(); + * console.log(count); // 10 + * ``` + * + * The original idea comes from [flush-promises] package in npm. + * + * [flush-promises]: https://www.npmjs.com/package/flush-promises + */ +export function flushPromises(): Promise { + return new Promise((resolve) => setTimeout(resolve)); +} diff --git a/flush_promises_test.ts b/flush_promises_test.ts new file mode 100644 index 0000000..1d046bd --- /dev/null +++ b/flush_promises_test.ts @@ -0,0 +1,18 @@ +import { test } from "@cross/test"; +import { assertEquals } from "@std/assert"; +import { flushPromises } from "./flush_promises.ts"; + +test( + "flushPromises() flushes all pending promises in the microtask queue", + async () => { + let count = 0; + Array.from({ length: 5 }).forEach(() => { + Promise.resolve() + .then(() => count++) + .then(() => count++); + }); + assertEquals(count, 0); + await flushPromises(); + assertEquals(count, 10); + }, +); From 1fe9f59b5f82baaddf938585012100b80477e6cd Mon Sep 17 00:00:00 2001 From: Alisue Date: Tue, 20 Aug 2024 23:53:21 +0900 Subject: [PATCH 2/7] feat(peekPromiseState): add `peekPromiseState` function --- deno.jsonc | 2 ++ peek_promise_state.ts | 41 +++++++++++++++++++++++++++++++++++++ peek_promise_state_bench.ts | 29 ++++++++++++++++++++++++++ peek_promise_state_test.ts | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 peek_promise_state.ts create mode 100644 peek_promise_state_bench.ts create mode 100644 peek_promise_state_test.ts diff --git a/deno.jsonc b/deno.jsonc index 9aa9e66..976c35e 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -10,6 +10,7 @@ "./lock": "./lock.ts", "./mutex": "./mutex.ts", "./notify": "./notify.ts", + "./peek-promise-state": "./peek_promise_state.ts", "./promise-state": "./promise_state.ts", "./queue": "./queue.ts", "./rw-lock": "./rw_lock.ts", @@ -41,6 +42,7 @@ "@core/asyncutil/lock": "./lock.ts", "@core/asyncutil/mutex": "./mutex.ts", "@core/asyncutil/notify": "./notify.ts", + "@core/asyncutil/peek-promise-state": "./peek_promise_state.ts", "@core/asyncutil/promise-state": "./promise_state.ts", "@core/asyncutil/queue": "./queue.ts", "@core/asyncutil/rw-lock": "./rw_lock.ts", diff --git a/peek_promise_state.ts b/peek_promise_state.ts new file mode 100644 index 0000000..1abbd99 --- /dev/null +++ b/peek_promise_state.ts @@ -0,0 +1,41 @@ +const t = Symbol("pending mark"); + +/** + * Promise state + */ +export type PromiseState = "fulfilled" | "rejected" | "pending"; + +/** + * Peek the current state (fulfilled, rejected, or pending) of the promise. + * + * ```ts + * import { assertEquals } from "@std/assert"; + * import { peekPromiseState } from "@core/asyncutil/peek-promise-state"; + * + * assertEquals(await peekPromiseState(Promise.resolve("value")), "fulfilled"); + * assertEquals(await peekPromiseState(Promise.reject("error")), "rejected"); + * assertEquals(await peekPromiseState(new Promise(() => {})), "pending"); + * ``` + * + * Use {@linkcode https://jsr.io/@core/asyncutil/doc/flush-promises/~/flushPromises flushPromises} + * to wait for all pending promises to be resolved prior to calling this function. + * + * ```ts + * import { assertEquals } from "@std/assert"; + * import { flushPromises } from "@core/asyncutil/flush-promises"; + * import { peekPromiseState } from "@core/asyncutil/peek-promise-state"; + * + * const p = Promise.resolve(undefined) + * .then(() => {}) + * .then(() => {}); + * assertEquals(await peekPromiseState(p), "pending"); + * await flushPromises(); + * assertEquals(await peekPromiseState(p), "fulfilled"); + * ``` + */ +export function peekPromiseState(p: Promise): Promise { + return Promise.race([p, t]).then( + (v) => (v === t ? "pending" : "fulfilled"), + () => "rejected", + ); +} diff --git a/peek_promise_state_bench.ts b/peek_promise_state_bench.ts new file mode 100644 index 0000000..e6523d9 --- /dev/null +++ b/peek_promise_state_bench.ts @@ -0,0 +1,29 @@ +import { peekPromiseState } from "./peek_promise_state.ts"; + +Deno.bench({ + name: "current", + fn: async () => { + await peekPromiseState(Promise.resolve("fulfilled")); + }, + group: "peekPromiseState (fulfilled)", + baseline: true, +}); + +Deno.bench({ + name: "current", + fn: async () => { + const p = Promise.reject("reject").catch(() => {}); + await peekPromiseState(p); + }, + group: "peekPromiseState (rejected)", + baseline: true, +}); + +Deno.bench({ + name: "current", + fn: async () => { + await peekPromiseState(new Promise(() => {})); + }, + group: "peekPromiseState (pending)", + baseline: true, +}); diff --git a/peek_promise_state_test.ts b/peek_promise_state_test.ts new file mode 100644 index 0000000..75c6eb2 --- /dev/null +++ b/peek_promise_state_test.ts @@ -0,0 +1,38 @@ +import { test } from "@cross/test"; +import { assertEquals } from "@std/assert"; +import { flushPromises } from "./flush_promises.ts"; +import { peekPromiseState } from "./peek_promise_state.ts"; + +test( + "peekPromiseState() returns 'fulfilled' for resolved promise", + async () => { + const p = Promise.resolve("Resolved promise"); + assertEquals(await peekPromiseState(p), "fulfilled"); + }, +); + +test( + "peekPromiseState() returns 'rejected' for rejected promise", + async () => { + const p = Promise.reject("Rejected promise"); + p.catch(() => undefined); // Avoid 'Uncaught (in promise) Rejected promise' + assertEquals(await peekPromiseState(p), "rejected"); + }, +); + +test( + "peekPromiseState() returns 'pending' for not resolved promise", + async () => { + const p = new Promise(() => undefined); + assertEquals(await peekPromiseState(p), "pending"); + }, +); + +test("peekPromiseState() return the current state of the promise", async () => { + const p = Promise.resolve(undefined) + .then(() => {}) + .then(() => {}); + assertEquals(await peekPromiseState(p), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(p), "fulfilled"); +}); From 236fa0cce956e22630b1eba999702cfb7176d859 Mon Sep 17 00:00:00 2001 From: Alisue Date: Tue, 20 Aug 2024 23:56:00 +0900 Subject: [PATCH 3/7] feat(promiseState): deprecate `promiseState` In favor of `peekPromiseState` and `flushPromises`. ```ts import { flushPromises } from "@core/asyncutil/flush-promises.ts"; import { peekPromiseState } from "@core/asyncutil/peek-promise-state"; const p = Promise.resolve(1) .then(() => 2) .then(() => 3); await flushPromises(); console.log(await peekPromiseState(p)); // "fulfilled" ``` --- promise_state.ts | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/promise_state.ts b/promise_state.ts index 4be0408..631b93d 100644 --- a/promise_state.ts +++ b/promise_state.ts @@ -1,7 +1,5 @@ -/** - * Promise state - */ -export type PromiseState = "fulfilled" | "rejected" | "pending"; +import { flushPromises } from "./flush_promises.ts"; +import { peekPromiseState, type PromiseState } from "./peek_promise_state.ts"; /** * Return state (fulfilled/rejected/pending) of a promise @@ -14,16 +12,12 @@ export type PromiseState = "fulfilled" | "rejected" | "pending"; * assertEquals(await promiseState(Promise.reject("error")), "rejected"); * assertEquals(await promiseState(new Promise(() => {})), "pending"); * ``` + * + * @deprecated Use {@linkcode https://jsr.io/@core/asyncutil/doc/peek-promise-state/~/peekPromiseState peekPromiseState} with {@linkcode https://jsr.io/@core/asyncutil/doc/flush-promises/~/flushPromises flushPromises} instead. */ export async function promiseState(p: Promise): Promise { - // NOTE: - // This 0 delay promise is required to refresh internal states of promises - await new Promise((resolve) => { - setTimeout(() => resolve(), 0); - }); - const t = {}; - return Promise.race([p, t]).then( - (v) => (v === t ? "pending" : "fulfilled"), - () => "rejected", - ); + await flushPromises(); + return peekPromiseState(p); } + +export type { PromiseState }; From 7b6e4e86c1a17b3c8eba1274464b7b9654e39525 Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 21 Aug 2024 00:02:53 +0900 Subject: [PATCH 4/7] test: use `peekPromiseState` instead `promiseState` becomes deprecated so we use `peekPromiseState` with `flushPromises` instead. --- notify_test.ts | 53 ++++++++++++++++++++++++++++--------------------- queue_test.ts | 24 ++++++++++++++-------- rw_lock_test.ts | 23 ++++++++++++--------- stack_test.ts | 24 ++++++++++++++-------- 4 files changed, 76 insertions(+), 48 deletions(-) diff --git a/notify_test.ts b/notify_test.ts index bd96902..b756ef9 100644 --- a/notify_test.ts +++ b/notify_test.ts @@ -1,7 +1,8 @@ import { test } from "@cross/test"; import { delay } from "@std/async/delay"; import { assertEquals, assertRejects, assertThrows } from "@std/assert"; -import { promiseState } from "./promise_state.ts"; +import { flushPromises } from "./flush_promises.ts"; +import { peekPromiseState } from "./peek_promise_state.ts"; import { Notify } from "./notify.ts"; test("Notify 'notify' wakes up a single waiter", async () => { @@ -11,14 +12,16 @@ test("Notify 'notify' wakes up a single waiter", async () => { assertEquals(notify.waiterCount, 2); notify.notify(); + await flushPromises(); assertEquals(notify.waiterCount, 1); - assertEquals(await promiseState(waiter1), "fulfilled"); - assertEquals(await promiseState(waiter2), "pending"); + assertEquals(await peekPromiseState(waiter1), "fulfilled"); + assertEquals(await peekPromiseState(waiter2), "pending"); notify.notify(); + await flushPromises(); assertEquals(notify.waiterCount, 0); - assertEquals(await promiseState(waiter1), "fulfilled"); - assertEquals(await promiseState(waiter2), "fulfilled"); + assertEquals(await peekPromiseState(waiter1), "fulfilled"); + assertEquals(await peekPromiseState(waiter2), "fulfilled"); }); test("Notify 'notify' wakes up a multiple waiters", async () => { @@ -31,28 +34,31 @@ test("Notify 'notify' wakes up a multiple waiters", async () => { assertEquals(notify.waiterCount, 5); notify.notify(2); + await flushPromises(); assertEquals(notify.waiterCount, 3); - assertEquals(await promiseState(waiter1), "fulfilled"); - assertEquals(await promiseState(waiter2), "fulfilled"); - assertEquals(await promiseState(waiter3), "pending"); - assertEquals(await promiseState(waiter4), "pending"); - assertEquals(await promiseState(waiter5), "pending"); + assertEquals(await peekPromiseState(waiter1), "fulfilled"); + assertEquals(await peekPromiseState(waiter2), "fulfilled"); + assertEquals(await peekPromiseState(waiter3), "pending"); + assertEquals(await peekPromiseState(waiter4), "pending"); + assertEquals(await peekPromiseState(waiter5), "pending"); notify.notify(2); + await flushPromises(); assertEquals(notify.waiterCount, 1); - assertEquals(await promiseState(waiter1), "fulfilled"); - assertEquals(await promiseState(waiter2), "fulfilled"); - assertEquals(await promiseState(waiter3), "fulfilled"); - assertEquals(await promiseState(waiter4), "fulfilled"); - assertEquals(await promiseState(waiter5), "pending"); + assertEquals(await peekPromiseState(waiter1), "fulfilled"); + assertEquals(await peekPromiseState(waiter2), "fulfilled"); + assertEquals(await peekPromiseState(waiter3), "fulfilled"); + assertEquals(await peekPromiseState(waiter4), "fulfilled"); + assertEquals(await peekPromiseState(waiter5), "pending"); notify.notify(2); + await flushPromises(); assertEquals(notify.waiterCount, 0); - assertEquals(await promiseState(waiter1), "fulfilled"); - assertEquals(await promiseState(waiter2), "fulfilled"); - assertEquals(await promiseState(waiter3), "fulfilled"); - assertEquals(await promiseState(waiter4), "fulfilled"); - assertEquals(await promiseState(waiter5), "fulfilled"); + assertEquals(await peekPromiseState(waiter1), "fulfilled"); + assertEquals(await peekPromiseState(waiter2), "fulfilled"); + assertEquals(await peekPromiseState(waiter3), "fulfilled"); + assertEquals(await peekPromiseState(waiter4), "fulfilled"); + assertEquals(await peekPromiseState(waiter5), "fulfilled"); }); test("Notify 'notifyAll' wakes up all waiters", async () => { @@ -62,9 +68,10 @@ test("Notify 'notifyAll' wakes up all waiters", async () => { assertEquals(notify.waiterCount, 2); notify.notifyAll(); + await flushPromises(); assertEquals(notify.waiterCount, 0); - assertEquals(await promiseState(waiter1), "fulfilled"); - assertEquals(await promiseState(waiter2), "fulfilled"); + assertEquals(await peekPromiseState(waiter1), "fulfilled"); + assertEquals(await peekPromiseState(waiter2), "fulfilled"); }); test( @@ -74,7 +81,7 @@ test( const notify = new Notify(); const waiter = notify.notified({ signal: controller.signal }); - assertEquals(await promiseState(waiter), "pending"); + assertEquals(await peekPromiseState(waiter), "pending"); }, ); diff --git a/queue_test.ts b/queue_test.ts index a91d912..0f92f3d 100644 --- a/queue_test.ts +++ b/queue_test.ts @@ -1,7 +1,8 @@ import { test } from "@cross/test"; import { delay } from "@std/async/delay"; import { assertEquals, assertRejects } from "@std/assert"; -import { promiseState } from "./promise_state.ts"; +import { flushPromises } from "./flush_promises.ts"; +import { peekPromiseState } from "./peek_promise_state.ts"; import { Queue } from "./queue.ts"; test("Queue 'pop' returns pushed items", async () => { @@ -17,9 +18,11 @@ test("Queue 'pop' returns pushed items", async () => { test("Queue 'pop' waits for an item is pushed", async () => { const q = new Queue(); const popper = q.pop(); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); q.push(1); - assertEquals(await promiseState(popper), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "fulfilled"); assertEquals(await popper, 1); }); @@ -27,7 +30,8 @@ test("Queue 'pop' with non-aborted signal", async () => { const controller = new AbortController(); const q = new Queue(); const popper = q.pop({ signal: controller.signal }); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); }); test("Queue 'pop' with signal aborted after delay", async () => { @@ -61,17 +65,21 @@ test("Queue 'pop' with signal already aborted", async () => { test("Queue with falsy value is accepted", async () => { const q = new Queue(); const popper = q.pop(); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); q.push(0); - assertEquals(await promiseState(popper), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "fulfilled"); assertEquals(await popper, 0); }); test("Queue with null is accepted", async () => { const q = new Queue(); const popper = q.pop(); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); q.push(null); - assertEquals(await promiseState(popper), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "fulfilled"); assertEquals(await popper, null); }); diff --git a/rw_lock_test.ts b/rw_lock_test.ts index 2893b4f..50b30cb 100644 --- a/rw_lock_test.ts +++ b/rw_lock_test.ts @@ -1,6 +1,7 @@ import { test } from "@cross/test"; import { assertEquals } from "@std/assert"; -import { promiseState } from "./promise_state.ts"; +import { flushPromises } from "./flush_promises.ts"; +import { peekPromiseState } from "./peek_promise_state.ts"; import { AsyncValue } from "./async_value.ts"; import { RwLock } from "./rw_lock.ts"; @@ -89,11 +90,13 @@ test( }; const r = reader(); const w = writer(); - assertEquals(await promiseState(r), "pending"); - assertEquals(await promiseState(w), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(r), "pending"); + assertEquals(await peekPromiseState(w), "pending"); resolve(); - assertEquals(await promiseState(r), "fulfilled"); - assertEquals(await promiseState(w), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(r), "fulfilled"); + assertEquals(await peekPromiseState(w), "fulfilled"); }, ); @@ -114,10 +117,12 @@ test( }; const w = writer(); const r = reader(); - assertEquals(await promiseState(w), "pending"); - assertEquals(await promiseState(r), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(w), "pending"); + assertEquals(await peekPromiseState(r), "pending"); resolve(); - assertEquals(await promiseState(w), "fulfilled"); - assertEquals(await promiseState(r), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(w), "fulfilled"); + assertEquals(await peekPromiseState(r), "fulfilled"); }, ); diff --git a/stack_test.ts b/stack_test.ts index 125d4b4..0e0d0af 100644 --- a/stack_test.ts +++ b/stack_test.ts @@ -1,7 +1,8 @@ import { test } from "@cross/test"; import { delay } from "@std/async/delay"; import { assertEquals, assertRejects } from "@std/assert"; -import { promiseState } from "./promise_state.ts"; +import { flushPromises } from "./flush_promises.ts"; +import { peekPromiseState } from "./peek_promise_state.ts"; import { Stack } from "./stack.ts"; test("Stack 'pop' returns pushed items", async () => { @@ -17,9 +18,11 @@ test("Stack 'pop' returns pushed items", async () => { test("Stack 'pop' waits for an item is pushed", async () => { const q = new Stack(); const popper = q.pop(); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); q.push(1); - assertEquals(await promiseState(popper), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "fulfilled"); assertEquals(await popper, 1); }); @@ -27,7 +30,8 @@ test("Stack 'pop' with non-aborted signal", async () => { const controller = new AbortController(); const q = new Stack(); const popper = q.pop({ signal: controller.signal }); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); }); test("Stack 'pop' with signal aborted after delay", async () => { @@ -61,17 +65,21 @@ test("Stack 'pop' with signal already aborted", async () => { test("Stack with falsy value is accepted", async () => { const q = new Stack(); const popper = q.pop(); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); q.push(0); - assertEquals(await promiseState(popper), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "fulfilled"); assertEquals(await popper, 0); }); test("Stack with null is accepted", async () => { const q = new Stack(); const popper = q.pop(); - assertEquals(await promiseState(popper), "pending"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "pending"); q.push(null); - assertEquals(await promiseState(popper), "fulfilled"); + await flushPromises(); + assertEquals(await peekPromiseState(popper), "fulfilled"); assertEquals(await popper, null); }); From 55c6d173d80976d18125f20620925c84854a8be4 Mon Sep 17 00:00:00 2001 From: Alisue Date: Tue, 20 Aug 2024 03:56:16 +0900 Subject: [PATCH 5/7] test: add benchmark for `promiseState` --- promise_state_bench.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 promise_state_bench.ts diff --git a/promise_state_bench.ts b/promise_state_bench.ts new file mode 100644 index 0000000..7116aa2 --- /dev/null +++ b/promise_state_bench.ts @@ -0,0 +1,29 @@ +import { promiseState } from "./promise_state.ts"; + +Deno.bench({ + name: "current", + fn: async () => { + await promiseState(Promise.resolve("fulfilled")); + }, + group: "promiseState (fulfilled)", + baseline: true, +}); + +Deno.bench({ + name: "current", + fn: async () => { + const p = Promise.reject("reject").catch(() => {}); + await promiseState(p); + }, + group: "promiseState (rejected)", + baseline: true, +}); + +Deno.bench({ + name: "current", + fn: async () => { + await promiseState(new Promise(() => {})); + }, + group: "promiseState (pending)", + baseline: true, +}); From b6adcfaabad7113372a4a97197e980aa4c672697 Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 21 Aug 2024 00:09:31 +0900 Subject: [PATCH 6/7] docs(flushPromises): add `flushPromises` section to README --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 22c6e19..66405ba 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,25 @@ const p2 = ensurePromise("Not a promise"); console.log(await p2); // Not a promise ``` +### flushPromises + +`flushPromises` flushes all pending promises in the microtask queue. + +```ts +import { flushPromises } from "@core/asyncutil/flush-promises"; + +let count = 0; +Array.from({ length: 5 }).forEach(() => { + Promise.resolve() + .then(() => count++) + .then(() => count++); +}); + +console.log(count); // 0 +await flushPromises(); +console.log(count); // 10 +``` + ### Lock/RwLock `Lock` is a mutual exclusion lock that provides safe concurrent access to a From 45c948e0c86784d966f1dff5060b5a81ea6c4d92 Mon Sep 17 00:00:00 2001 From: Alisue Date: Wed, 21 Aug 2024 00:09:48 +0900 Subject: [PATCH 7/7] docs(peekPromiseState): replace `promiseState` to `peekPromiseState` --- README.md | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 66405ba..60cfd33 100644 --- a/README.md +++ b/README.md @@ -175,22 +175,37 @@ assertEquals(await promiseState(waiter1), "fulfilled"); assertEquals(await promiseState(waiter2), "fulfilled"); ``` -### promiseState +### peekPromiseState -`promiseState` is used to determine the state of the promise. Mainly for testing -purpose. +`peekPromiseState` is used to determine the state of the promise. Mainly for +testing purpose. ```typescript -import { promiseState } from "@core/asyncutil/promise-state"; +import { peekPromiseState } from "@core/asyncutil/peek-promise-state"; const p1 = Promise.resolve("Resolved promise"); -console.log(await promiseState(p1)); // fulfilled +console.log(await peekPromiseState(p1)); // fulfilled const p2 = Promise.reject("Rejected promise").catch(() => undefined); -console.log(await promiseState(p2)); // rejected +console.log(await peekPromiseState(p2)); // rejected const p3 = new Promise(() => undefined); -console.log(await promiseState(p3)); // pending +console.log(await peekPromiseState(p3)); // pending +``` + +Use `flushPromises` to wait all pending promises to resolve. + +```typescript +import { flushPromises } from "@core/asyncutil/flush-promises"; +import { peekPromiseState } from "@core/asyncutil/peek-promise-state"; + +const p = Promise.resolve(undefined) + .then(() => {}) + .then(() => {}); + +console.log(await peekPromiseState(p)); // pending +await flushPromises(); +console.log(await peekPromiseState(p)); // fulfilled ``` ### Queue/Stack