forked from netlify/staticgen
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththrottle-concurrency.js
More file actions
37 lines (35 loc) · 1.08 KB
/
throttle-concurrency.js
File metadata and controls
37 lines (35 loc) · 1.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
async function access(pending, queue, resource, ...args) {
try {
const promise = resource(...args)
pending.push(promise)
await promise
const idx = pending.indexOf(promise)
pending.splice([idx, 1, ...(queue[0] ? [queue.shift()()] : [])])
return promise
} catch (err) {
console.error(err)
throw err
}
}
function delay(boundAccess, queue, timeout, ...args) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject()
const idx = queue.indexOf(resolve)
queue.splice(idx, 1)
}, timeout)
const delayedResolve = async () => {
clearTimeout(timeoutId)
const resp = await boundAccess(...args)
resolve(resp)
}
queue.push(delayedResolve)
})
}
module.exports = function throttleConcurrency(resource, limit, timeout = 10000) {
const pending = []
const queue = []
const boundAccess = access.bind(null, pending, queue, resource)
const boundDelay = delay.bind(null, boundAccess, queue, timeout)
return (...args) => (pending.length < limit ? boundAccess : boundDelay)(...args)
}