Skip to content

Instantly share code, notes, and snippets.

@ryunp
Last active February 19, 2020 01:18
Show Gist options
  • Save ryunp/806fdf8a6d00035934028a9408753ad9 to your computer and use it in GitHub Desktop.
Save ryunp/806fdf8a6d00035934028a9408753ad9 to your computer and use it in GitHub Desktop.
/** Ryan Paul 12/25/19
A debouncer wraps a function with a delayed execution timer.
Calling the debounced function before the delay elapsed will reset the
execution timer.
*/
function debounce (callback, delay) {
var timer = null
function delayExecution (...args) {
if (timer) {
clearTimeout(timer)
}
console.log(`${timer ? "Reset. " : ""}Execution in ${delay}ms...`)
timer = setTimeout(() => {
callback(...args)
timer = null
}, delay)
}
delayExecution.clear = () => {
clearTimeout(timer)
timer = null
}
return delayExecution
}
// Standard function
function logSquare (val) {
console.log(val * val)
}
// Create a debounced version of our function
var logSquareDebounced = debounce(logSquare, 2000)
// Call the function every 1.5 seconds with a new argument
for (let i = 1; i <= 5; i++) {
void setTimeout(logSquareDebounced.bind(null, i), i * 500)
}
// Wait for completion, 1 second after test a few more
for (let i = 1; i <= 2; i++) {
void setTimeout(logSquareDebounced.bind(null, i), 5000 + (i * 500))
}
/** Ryan Paul 1/7/20
A debouncer wraps a function with a delayed execution timer. Promise version.
Calling the debounced function before the delay elapsed will reset the
execution timer and reject the previous promise attempt.
*/
function debouncePromise (callback, delay) {
var timer = null
var prevReject = null
function delayExecution (...args) {
return new Promise(executor)
function executor (resolve, reject) {
// Reset time handler if called within timeout delay
if (timer) {
clearTimeout(timer)
prevReject("Called again before timer")
}
// Save current reject callback for future timer interupts
prevReject = reject
// Set timeout for next callback
console.log(`${timer ? "Reset. " : ""}Execution in ${delay}ms...`)
timer = setTimeout(() => {
timer = prevReject = null
console.log("timer complete, running callback")
resolve(callback(...args))
}, delay)
}
}
// Provides a cancellable interface for the current timer
delayExecution.clear = () => {
clearTimeout(timer)
timer = null
prevReject("Delayed execution cancelled")
prevReject = null
}
return delayExecution
}
// Mockup for promise-based delayed operation (File IO)
function mockFileWritePromise (path, data) {
return new Promise(executor)
function executor (resolve) {
setTimeout(action, 2000)
function action () {
resolve(`${data.length} bytes written to ${path}`)
}
}
}
// Promise-based delayed logging of given string
function delayedLogPromise (result) {
return new Promise(executor)
function executor (resolve) {
setTimeout(action, 1000)
function action () {
console.log(result)
resolve()
}
}
}
// No comment
function square (val) {
return val * val
}
var promises
function testFunctionCallback () {
promises = []
// Create a new timed promise execution context
const squareDebouncedPromise = debouncePromise(square, 5000)
// Repeatedly call the delayed execution function
for (let i = 1; i < 5; i++) {
const promise = squareDebouncedPromise(i)
promises.push(promise)
promise.then(result => console.log(`#${i}`, result), console.error)
}
// Immediately show the promise states
promises.forEach(promise => console.log(promise))
// Show state of last debounced promise after it has completed
const lastPromise = promises[promises.length - 1]
lastPromise.then(() => console.log(lastPromise))
}
function testPromiseCallback () {
promises = []
const fileWriteDebouncedPromise = debouncePromise(mockFileWritePromise, 5000)
for (let i = 0; i < 4; i++) {
const file = `MyFile-${i}.txt`
const text = "My Data".repeat(i)
const promise = fileWriteDebouncedPromise(file, text)
promises.push(promise)
promise.then(delayedLogPromise, console.error)
}
promises.forEach(promise => console.log(promise))
const lastPromise = promises[promises.length - 1]
lastPromise.then(() => console.log(lastPromise))
}
/* Best to examine the results one at a time */
// testFunctionCallback()
// testPromiseCallback()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment