@antora/assembler
Version:
A JavaScript library that merges AsciiDoc content from multiple pages in an Antora site into assembly files and delegates to an exporter to convert those files to another format, such as PDF.
58 lines (52 loc) • 1.5 kB
JavaScript
'use strict'
class PromiseQueue {
#scheduler
#started
#pending
#rejection
#startTask
#trapRejection
constructor ({ concurrency = Infinity } = {}) {
this.concurrency = concurrency
this.#scheduler = Promise.resolve()
this.#started = []
this.#pending = []
this.#startTask = (task) => {
if (this.#rejection) return
if (this.concurrency === Infinity) {
this.#started.push(task().catch(this.#trapRejection))
} else {
let current
this.#pending.push(
(current = task()
.catch(this.#trapRejection)
.finally(() => this.#pending.splice(this.#pending.indexOf(current), 1)))
)
this.#started.push(current)
}
}
this.#trapRejection = (err) => (this.#rejection = err || new Error()) && undefined
}
add (tasks) {
if (!Array.isArray(tasks)) tasks = [tasks]
for (const task of tasks) {
if (this.#pending.length < this.concurrency) {
this.#startTask(task)
} else {
this.#scheduler = this.#scheduler.then(
() => this.#pending.length && Promise.race(this.#pending).then(() => this.#startTask(task))
)
}
}
return this
}
async toPromise () {
// what about promiseAll(), all(), or promise()?
await this.#scheduler
return Promise.all(this.#started).then((returnValues) => {
if (this.#rejection) throw this.#rejection
return returnValues
})
}
}
module.exports = PromiseQueue