cleaner promise_interval

This commit is contained in:
Henry Jameson 2026-06-16 17:06:17 +03:00
commit 2b7b1835e9

View file

@ -4,32 +4,38 @@
// time after the first interval. // time after the first interval.
// - interval is the interval delay in ms. // - interval is the interval delay in ms.
const wait = (timeout) => {
let timeoutId
const promise = () => new Promise((resolve) => {
timeoutId = window.setTimeout(() => resolve(), timeout)
})
return { timeoutId, promise }
}
export const promiseInterval = (promiseCall, interval) => { export const promiseInterval = (promiseCall, interval) => {
let stopped = false let stopped = false
let timeout = null let timeout = null
const func = () => {
const promise = promiseCall()
// something unexpected happened and promiseCall did not
// return a promise, abort the loop.
if (!(promise && promise.finally)) {
console.warn(
'promiseInterval: promise call did not return a promise, stopping interval.',
)
return
}
promise.finally(() => {
if (stopped) return
timeout = window.setTimeout(func, interval)
})
}
const stopFetcher = () => { const stopFetcher = () => {
stopped = true stopped = true
window.clearTimeout(timeout) window.clearTimeout(timeout)
} }
timeout = window.setTimeout(func, interval) const loop = new Promise(async (resolve, reject) => {
try {
while (!stopped) {
await promiseCall()
const { timeoutId, promise } = wait(interval)
timeout = timeoutId
await promise()
}
resolve()
} catch (e) {
reject(e)
}
})
loop.then()
return { stop: stopFetcher } return { stop: stopFetcher }
} }