78 lines
2.5 KiB
JavaScript
78 lines
2.5 KiB
JavaScript
"use strict";
|
|
|
|
/**
|
|
* @name Damper
|
|
*
|
|
* @description
|
|
* Execute multiple `function` calls in a `timeout` amount of time just once
|
|
*
|
|
* You may also know this technology as a "debouncer" (you are free to use any name)
|
|
* I prefer "damper", from the word "демпфер"
|
|
*
|
|
* @param {function} function Function to execute after damping
|
|
* @param {number} timeout Timer in milliseconds (ms)
|
|
* @param {number} force Argument number storing the status of enforcement execution (see @example)
|
|
*
|
|
* @return {Promise}
|
|
*
|
|
* @example <caption>Forced execution</caption>
|
|
* const dampered = damper(
|
|
* (
|
|
* a, // 0
|
|
* b, // 1
|
|
* c, // 2
|
|
* force = false, // 3
|
|
* d, // 4
|
|
* resolve,
|
|
* reject
|
|
* ) => {},
|
|
* 500,
|
|
* 3, // 3 -> the "force" argument
|
|
* );
|
|
*
|
|
* dampered('for a', 'for b', 'for c', true, 'for d'); // Enabled forced execution
|
|
*
|
|
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
|
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
|
*/
|
|
export function damper(func, timeout = 300, force) {
|
|
// Declaring the timer for executing the function
|
|
let timer;
|
|
|
|
return ((...args) => {
|
|
return new Promise((resolve, reject) => {
|
|
// Deinitializing the timer
|
|
clearTimeout(timer);
|
|
|
|
if (typeof force === "number" && args[force]) {
|
|
// Forced execution (ignoring the timer)
|
|
|
|
// Deleting the force argument
|
|
if (typeof force === "number") args = [
|
|
...args.splice(0, force),
|
|
...args.splice(force + 1)
|
|
];
|
|
|
|
// Writing promise handlers into the arguments variable
|
|
args.push(resolve, reject);
|
|
|
|
// Executing the function
|
|
func.apply(this, args);
|
|
} else {
|
|
// Normal execution
|
|
|
|
// Deleting the force argument
|
|
if (typeof force === "number") args = [
|
|
...args.splice(0, force),
|
|
...args.splice(force + 1)
|
|
];
|
|
|
|
// Writing promise handlers into the arguments variable
|
|
args.push(resolve, reject);
|
|
|
|
// Reinitializing the timer and executing the function when the timer expires
|
|
timer = setTimeout(() => func.apply(this, args), timeout);
|
|
}
|
|
});
|
|
});
|
|
} |