Add debouncing settle detection

This commit is contained in:
Jonathan Tran
2024-12-03 17:39:41 -05:00
parent fe83cd94ca
commit 5ab814d153

View File

@ -1,3 +1,5 @@
import { debounce } from './utils'
/** /**
* A registry for tracking background work and reacting once all work has * A registry for tracking background work and reacting once all work has
* settled. * settled.
@ -6,17 +8,23 @@ export class PromiseRegistry {
outstanding: Array<TrackedPromise<unknown>> outstanding: Array<TrackedPromise<unknown>>
settleCallbacks: Array<() => void> settleCallbacks: Array<() => void>
/**
* This reduces overhead when there are many promises all settling around the
* same time by trading some latency for when the overall settling is
* detected.
*/
private debouncedCleanUp: () => void
constructor() { constructor() {
this.outstanding = [] this.outstanding = []
this.settleCallbacks = [] this.settleCallbacks = []
this.debouncedCleanUp = debounce(this.attemptCleanUp.bind(this), 10)
} }
track<T>(promise: Promise<T>, onSettle?: () => void) { track<T>(promise: Promise<T>, onSettle?: () => void) {
// Since built-in Promises don't have a way to synchronously check if // Since built-in Promises don't have a way to synchronously check if
// they're settled, it cannot start out settled. // they're settled, it cannot start out settled.
this.outstanding.push( this.outstanding.push(new TrackedPromise(promise, this.debouncedCleanUp))
new TrackedPromise(promise, this.attemptCleanUp.bind(this))
)
if (onSettle) { if (onSettle) {
this.settleCallbacks.push(onSettle) this.settleCallbacks.push(onSettle)
} }
@ -78,8 +86,7 @@ class TrackedPromise<T> {
this.settled = false this.settled = false
this.inner = promise.finally(() => { this.inner = promise.finally(() => {
this.settled = true this.settled = true
// TODO: debounce? onSettle()
setTimeout(onSettle, 0)
}) })
} }
} }