Skip to content

Instantly share code, notes, and snippets.

@dmail
Created July 6, 2020 08:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmail/5de9a9dd54806c11728a9e178bfd255a to your computer and use it in GitHub Desktop.
Save dmail/5de9a9dd54806c11728a9e178bfd255a to your computer and use it in GitHub Desktop.
debounce incoming requests ensuring max X requests are handled at the same time and debouncing gradually in batches
const debounce = (
fn,
{ debounceInterval = 50, maxConcurrentRequests = 15, unstackCount = 10 } = {},
) => {
let queue = []
let pendingCount = 0
const debouncedFn = async (request) => {
let entry
const promise = new Promise((resolve, reject) => {
entry = { request, resolve, reject }
})
if (pendingCount < maxConcurrentRequests) {
perform(entry)
return promise
}
queue.push(entry)
return promise
}
const perform = async ({ request, resolve, reject }) => {
try {
const value = await fn(request)
pendingCount--
resolve(value)
} catch (e) {
pendingCount--
reject(e)
}
}
const tick = () => {
const todo = queue.slice(0, unstackCount)
queue = queue.slice(unstackCount)
todo.forEach(perform)
}
const interval = setInterval(tick, debounceInterval)
debouncedFn.cancel = () => {
clearInterval(interval)
}
return debouncedFn
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment