import { TypeVoidFunction } from '../types';
/**
* throttle
<iframe
src="https://codesandbox.io/embed/nonollcode-snippet-9gko8?autoresize=1&expanddevtools=1&fontsize=14&hidenavigation=1&initialpath=%2Ffunctions-throttle.html&module=%2Ffunctions-throttle.html&theme=dark"
style="width:100%; height:500px; border:1px solid black; border-radius: 4px; overflow:hidden;"
title="@nonoll/code-snippet"
allow="geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb"
sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"
></iframe>
* @memberof module:functions
* @function
* @see https://css-tricks.com/debouncing-throttling-explained-examples/
* @param {TypeVoidFunction} fn
* @param {Number} [delay=0]
* @returns {TypeVoidFunction}
* @example
import { debounce } from '@nonoll/code-snippet/functions';
const forExample = () => {
const delay = 1000 * 1;
const listener = throttle(res => console.log(res), delay);
listener(`1 ${new Date()}`);
listener('2');
listener('3');
listener('4');
setTimeout(() => {
listener(`5 ${new Date()}`);
}, delay);
}
forExample();
*/
export const throttle = (fn: TypeVoidFunction, /* istanbul ignore next */ delay: number = 0): TypeVoidFunction => {
const caller = (args: any[]) => {
fn.apply(null, args);
base = +new Date();
};
let base = null;
let isLeading = true;
let stamp = null;
return (...args: any[]) => {
if (isLeading) {
caller(args);
isLeading = false;
return;
}
stamp = +new Date();
/* istanbul ignore next */
base = base || stamp;
if ((stamp - base) >= delay) {
/* istanbul ignore next */
caller(args);
}
};
};