Skip to content

Instantly share code, notes, and snippets.

@fxg42
Last active May 8, 2017 14:15
Show Gist options
  • Save fxg42/868552c24370261108859a05a06a2c94 to your computer and use it in GitHub Desktop.
Save fxg42/868552c24370261108859a05a06a2c94 to your computer and use it in GitHub Desktop.
Rate limiting a Promise returning function
// heavily inspired by https://github.com/JMPerez/promise-throttle
const throttle = (f, rate) => {
// rate is # of calls/sec
const period = 1/rate * 1000 // minimum elapsed time (in ms) between calls (sec/call * 1000ms/sec)
const queue = [ ] // queued function calls
let last = 0 // last time `f` was called
const applyNext = () => {
if (queue.length === 0) return
const now = new Date()
const since = now - last // elapsed time since last call
if (since >= period) {
last = now
const { f, args, resolve, reject } = queue.shift()
f(...args).then(resolve).catch(reject)
} else {
setTimeout(applyNext, period - since) // try again at start of next period
}
}
return (...args) => new Promise((resolve, reject) => {
queue.push({ f, args, resolve, reject })
applyNext()
})
}
// ...
const apiCall = throttle(async (query) => {
// ...
}, 50)
const main = async () => {
const queries = [ 'a', 'b', 'c' ]
const results = await Promise.all(queries.map(apiCall))
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment