class ThrottleDebounce {
static throttle(func, wait, options = {}) {
let isWaiting = false;
let lastArgs = null;
let timeoutId = null;
const startWaitingPeriod = () => {
timeoutId = setTimeout(() => {
if (options.trailing && lastArgs) {
func.apply(this, lastArgs);
lastArgs = null;
startWaitingPeriod();
} else {
isWaiting = false;
}
}, wait);
};
const wrapper = (...args) => {
if (!isWaiting) {
isWaiting = true;
if (options.leading) {
func.apply(this, args);
} else {
lastArgs = args;
}
startWaitingPeriod();
} else {
lastArgs = args;
}
};
wrapper.cancel = () => {
clearTimeout(timeoutId);
timeoutId = null;
isWaiting = false;
lastArgs = null;
};
return wrapper;
}
static debounce(func, wait, options = {}) {
let timeoutId;
const debounced = (...args) => {
const context = this;
const callNow = options.leading && !timeoutId;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
timeoutId = null;
if (options.trailing && !callNow) {
func.apply(context, args);
}
}, wait);
if (callNow) {
func.apply(context, args);
}
};
debounced.cancel = () => {
clearTimeout(timeoutId);
timeoutId = null;
};
return debounced;
}
}
const throttle = ThrottleDebounce.throttle
const debounce = ThrottleDebounce.debounce