@gvray/eskit
Version:
A rich and colorful toolkit about typescript and javascript.
112 lines • 4.22 kB
JavaScript
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.throttle = throttle;
/**
* Creates a throttled function that only invokes the original function at most once per every `delay` milliseconds.
* The throttled function has optional leading or trailing invocation.
* 创建一个节流函数,在每个 `delay` 毫秒内最多只调用一次原函数。
* 节流函数可以选择在前沿或后沿调用。
*
* @param fn - The original function to be throttled. / 要被节流的原函数
* @param delay - The number of milliseconds to throttle. / 节流的毫秒数
* @param options - Optional configuration for leading and/or trailing invocation. / 前沿和/或后沿调用的可选配置
* @param options.leading - Specify invoking on the leading edge. Default is `false`. / 指定是否在前沿调用,默认为 `false`
* @param options.trailing - Specify invoking on the trailing edge. Default is `true`. / 指定是否在后沿调用,默认为 `true`
* @returns Throttled function / 节流函数
*
* @example
* ```typescript
* // Basic throttle
* const throttledFn = throttle(() => {
* console.log('Called!');
* }, 1000);
*
* // With leading edge
* const throttledWithLeading = throttle(() => {
* console.log('Called immediately!');
* }, 1000, { leading: true });
*
* // Search input example
* const searchThrottled = throttle((query: string) => {
* performSearch(query);
* }, 300);
* ```
*/
function throttle(fn, delay, options) {
if (options === void 0) { options = {}; }
var timerId = null;
var lastInvokeTime = 0;
var lastArgs;
var leadingInvoked = false;
var _a = options.leading, leading = _a === void 0 ? false : _a, _b = options.trailing, trailing = _b === void 0 ? true : _b;
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var now = Date.now();
var timeSinceLastInvoke = now - lastInvokeTime;
lastArgs = args;
// Clear existing timer
if (timerId !== null) {
clearTimeout(timerId);
timerId = null;
}
// Leading edge
if (leading && timeSinceLastInvoke >= delay) {
lastInvokeTime = now;
leadingInvoked = true;
fn.apply(void 0, __spreadArray([], __read(args), false));
// If only leading is enabled, don't set trailing timer
if (!trailing) {
return;
}
}
else {
leadingInvoked = false;
}
// Trailing edge
if (trailing) {
var remainingDelay = delay - timeSinceLastInvoke;
var timeToWait = remainingDelay > 0 ? remainingDelay : 0;
timerId = setTimeout(function () {
// Only invoke trailing if we didn't just invoke leading
if (!leadingInvoked) {
lastInvokeTime = Date.now();
if (lastArgs) {
fn.apply(void 0, __spreadArray([], __read(lastArgs), false));
}
}
timerId = null;
leadingInvoked = false;
}, timeToWait);
}
};
}
exports.default = throttle;
//# sourceMappingURL=throttle.js.map