Add debouncing settle detection
This commit is contained in:
@ -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)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user