mirror of https://github.com/vuejs/vitepress
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
38 lines
898 B
38 lines
898 B
// Asynchronous queue with a close method
|
|
export default class Queue<T> {
|
|
private queue: Array<T> = []
|
|
private pending: Array<(data: T | null) => void> = []
|
|
#closed: boolean = false
|
|
|
|
get closed() {
|
|
return this.#closed
|
|
}
|
|
|
|
async *items() {
|
|
while (true) {
|
|
const item = await this.dequeue()
|
|
if (item === null) break
|
|
yield item
|
|
}
|
|
}
|
|
|
|
enqueue(data: T) {
|
|
if (this.closed)
|
|
throw new Error(`Failed to enqueue ${data}, queue already closed`)
|
|
if (data === null) return this.close()
|
|
if (this.pending.length) this.pending.shift()!(data)
|
|
else this.queue.push(data)
|
|
}
|
|
|
|
async dequeue(): Promise<T | null> {
|
|
if (this.closed) return null
|
|
if (this.queue.length) return this.queue.shift()!
|
|
return new Promise((res) => this.pending.push(res))
|
|
}
|
|
|
|
close() {
|
|
this.#closed = true
|
|
for (const res of this.pending) res(null)
|
|
}
|
|
}
|