1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00
next.js/packages/next/lib/p-queue.js
Tim Neutkens b1c4f3aec4
Monorepo (#5341)
- Implements Lerna
- Moves all source code into `packages/next`
- Keeps integration tests in the root directory
2018-10-01 01:02:10 +02:00

84 lines
1.6 KiB
JavaScript

// based on https://github.com/sindresorhus/p-queue (MIT)
// modified for browser support
class Queue {
constructor () {
this._queue = []
}
enqueue (run) {
this._queue.push(run)
}
dequeue () {
return this._queue.shift()
}
get size () {
return this._queue.length
}
}
export default class PQueue {
constructor (opts) {
opts = Object.assign({
concurrency: Infinity,
queueClass: Queue
}, opts)
if (opts.concurrency < 1) {
throw new TypeError('Expected `concurrency` to be a number from 1 and up')
}
this.queue = new opts.queueClass() // eslint-disable-line new-cap
this._pendingCount = 0
this._concurrency = opts.concurrency
this._resolveEmpty = () => {}
}
_next () {
this._pendingCount--
if (this.queue.size > 0) {
this.queue.dequeue()()
} else {
this._resolveEmpty()
}
}
add (fn, opts) {
return new Promise((resolve, reject) => {
const run = () => {
this._pendingCount++
fn().then(
val => {
resolve(val)
this._next()
},
err => {
reject(err)
this._next()
}
)
}
if (this._pendingCount < this._concurrency) {
run()
} else {
this.queue.enqueue(run, opts)
}
})
}
onEmpty () {
return new Promise(resolve => {
const existingResolve = this._resolveEmpty
this._resolveEmpty = () => {
existingResolve()
resolve()
}
})
}
get size () {
return this.queue.size
}
get pending () {
return this._pendingCount
}
}