From bb29c191fb39a856c134f40ab2b1c65ab7ac9a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20Jos=C3=A9=20Pereira?= Date: Thu, 7 Mar 2024 14:57:25 -0300 Subject: [PATCH] core: frontend: Add one-more-time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Patrick José Pereira --- core/frontend/src/one-more-time.ts | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 core/frontend/src/one-more-time.ts diff --git a/core/frontend/src/one-more-time.ts b/core/frontend/src/one-more-time.ts new file mode 100644 index 000000000..1c2a7df6d --- /dev/null +++ b/core/frontend/src/one-more-time.ts @@ -0,0 +1,63 @@ +/** + * After multiple years and attempts + * This is a RAII class that takes advantage of the new disposable feature + * to create a promise that repeats itself until it's disposed + */ +class OneMoreTime { + private isDisposed = false + + constructor( + private readonly action: () => Promise, + private readonly timeout = 5000, + autostart = true, + ) { + // One more time + if (autostart) { + // eslint-disable-next-line no-return-await + (async () => await this.start())() + } + } + + async start(): Promise { + // Come on, alright + if (this.isDisposed) return + + try { + // One more time, we're gonna celebrate + await this.action() + } catch (error) { + console.error('Error in self-calling promise:', error) + // Oh yeah, alright, don't stop the dancing + // eslint-disable-next-line no-promise-executor-return + await new Promise((resolve) => setTimeout(resolve, this.timeout)) + } + + // One more time, a celebration + // eslint-disable-next-line no-return-await + (async () => await this.start())() + } + + // Celebrate and dance so free + [Symbol.dispose](): void { + this.stop() + } + + // Stop timer + stop(): void { + this.isDisposed = true + } +} + +/** Example + async function logTimestamp() { + console.log('Current timestamp:', new Date()) + await new Promise(resolve => setTimeout(resolve, 1000)) // Simulate some async work + } + + (async () => { + console.log("started") + using task = new OneMoreTime(logTimestamp) + await new Promise(resolve => setTimeout(resolve, 5000)) // Simulate some async work + console.log("done") + })() +*/