improve async queue
resolve the promise for the added task immediately, instead of waiting on a promise for all tasks
This commit is contained in:
@@ -1,25 +1,35 @@
|
|||||||
export type AsyncCallback = () => unknown
|
export type AsyncCallback<T> = () => T
|
||||||
|
|
||||||
|
type QueueItem = {
|
||||||
|
callback: AsyncCallback<unknown>
|
||||||
|
resolve: (value: unknown) => void
|
||||||
|
reject: (error: unknown) => void
|
||||||
|
}
|
||||||
|
|
||||||
export class AsyncQueue {
|
export class AsyncQueue {
|
||||||
private callbacks: AsyncCallback[] = []
|
private items: QueueItem[] = []
|
||||||
private promise: Promise<void> | undefined
|
private running = false
|
||||||
|
|
||||||
async add(callback: AsyncCallback) {
|
add<T>(callback: AsyncCallback<T>): Promise<Awaited<T>> {
|
||||||
this.callbacks.push(callback)
|
return new Promise((resolve, reject) => {
|
||||||
if (this.promise) return this.promise
|
this.items.push({ callback, resolve: resolve as any, reject })
|
||||||
|
void this.runQueue()
|
||||||
this.promise = this.runQueue()
|
})
|
||||||
try {
|
|
||||||
await this.promise
|
|
||||||
} finally {
|
|
||||||
this.promise = undefined
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async runQueue() {
|
private async runQueue() {
|
||||||
let callback: AsyncCallback | undefined
|
if (this.running) return
|
||||||
while ((callback = this.callbacks.shift())) {
|
this.running = true
|
||||||
await callback()
|
|
||||||
|
let item
|
||||||
|
while ((item = this.items.shift())) {
|
||||||
|
try {
|
||||||
|
item.resolve(await item.callback())
|
||||||
|
} catch (error) {
|
||||||
|
item.reject(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.running = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user