Last active
February 19, 2020 01:18
-
-
Save ryunp/806fdf8a6d00035934028a9408753ad9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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)) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** 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