From 9b54e80edd6f887183c2d85cac2a9c3a396e6f92 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Tue, 14 May 2024 23:30:54 +0200 Subject: [PATCH] [promise] implement untilAsync --- indexeddbV2.test.js | 1 - pledge.test.js | 4 ++-- promise.js | 20 +++++++++++++++++++- promise.test.js | 3 +++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/indexeddbV2.test.js b/indexeddbV2.test.js index 60f7843..f68d660 100644 --- a/indexeddbV2.test.js +++ b/indexeddbV2.test.js @@ -112,4 +112,3 @@ export const testBlocked = async () => { return idb.deleteDB(testDBName) }).promise() } - diff --git a/pledge.test.js b/pledge.test.js index 9cde0bd..2e00662 100644 --- a/pledge.test.js +++ b/pledge.test.js @@ -24,7 +24,7 @@ export const testPledgeCoroutine = async _tc => { * @param {t.TestCase} _tc */ export const testPledgeVsPromisePerformanceTimeout = async _tc => { - const iterations = 25000 + const iterations = 100 const waitTime = 0 await t.measureTimeAsync(`Awaiting ${iterations} callbacks (promise)`, async () => { for (let i = 0; i < iterations; i++) { @@ -48,7 +48,7 @@ export const testPledgeVsPromisePerformanceTimeout = async _tc => { * @param {t.TestCase} _tc */ export const testPledgeVsPromisePerformanceResolved = async _tc => { - const iterations = 25000 + const iterations = 100 t.measureTime(`Awaiting ${iterations} callbacks (only iterate)`, () => { for (let i = 0; i < iterations; i++) { /* nop */ } }) diff --git a/promise.js b/promise.js index 8254fc8..61eefe8 100644 --- a/promise.js +++ b/promise.js @@ -56,6 +56,7 @@ export const resolveWith = res => Promise.resolve(res) /** * @todo Next version, reorder parameters: check, [timeout, [intervalResolution]] + * @deprecated use untilAsync instead * * @param {number} timeout * @param {function():boolean} check @@ -80,11 +81,28 @@ export const until = (timeout, check, intervalResolution = 10) => create((resolv const intervalHandle = setInterval(untilInterval, intervalResolution) }) +/** + * @param {()=>Promise|boolean} check + * @param {number} timeout + * @param {number} intervalResolution + * @return {Promise} + */ +export const untilAsync = async (check, timeout = 0, intervalResolution = 10) => { + const startTime = time.getUnixTime() + const noTimeout = timeout <= 0 + // eslint-disable-next-line no-unmodified-loop-condition + while (noTimeout || time.getUnixTime() - startTime <= timeout) { + if (await check()) return + await wait(intervalResolution) + } + throw new Error('Timeout') +} + /** * @param {number} timeout * @return {Promise} */ -export const wait = timeout => create((resolve, reject) => setTimeout(resolve, timeout)) +export const wait = timeout => create((resolve, _reject) => setTimeout(resolve, timeout)) /** * Checks if an object is a promise using ducktyping. diff --git a/promise.test.js b/promise.test.js index 4aebb6b..a3eab39 100644 --- a/promise.test.js +++ b/promise.test.js @@ -38,8 +38,11 @@ export const testRepeatPromise = async _tc => { await promise.resolve() await measureP(promise.wait(10), 7, 1000) await measureP(failsP(promise.until(15, () => false)), 15, 1000) + await measureP(failsP(promise.untilAsync(() => false, 15)), 15, 1000) const startTime = time.getUnixTime() await measureP(promise.until(0, () => (time.getUnixTime() - startTime) > 100), 100, 1000) + const startTime2 = time.getUnixTime() + await measureP(promise.untilAsync(() => (time.getUnixTime() - startTime2) > 100), 100, 1000) await promise.all([promise.wait(5), promise.wait(10)]) }