/**
* 函数节流
* @param {function} func 需要节流的函数
* @param {number} interval 函数的执行间隔(毫秒)
* @param {object} options { leading: true, tailing: false }
*/
function throttle(func, interval, options) {
let canRun = false, // 是否可以执行函数
lastInvokeTime = 0, // 函数上一次被执行的时刻(时间戳)
tid = null; // 定时器id,设置间隔过后再次执行一次函数
// leading和tailing不能同时为false
const { leading = true, tailing = false } = options || {};
const throttled = function throttled(...args) {
let now = Date.now();
if (!lastInvokeTime) {
if (leading) {
canRun = true;
}
} else {
if (now - lastInvokeTime >= interval) {
canRun = true;
}
}
if (canRun) {
if (tid) {
clearTimeout(tid);
tid = null;
}
canRun = false;
lastInvokeTime = now;
func.apply(this, args);
} else if (!tid && tailing) {
tid = setTimeout(function () {
func.apply(this, args);
lastInvokeTime = 0;
tid = null;
}, now - lastInvokeTime);
}
}
/**
* 取消最后一次的函数执行
*/
throttled.cancel = function cancel() {
lastInvokeTime = 0;
if (tid) {
clearTimeout(tid);
tid = null;
}
}
return throttled;
}
// test
let count = 0;
function increment() {
count += 1;
console.log((new Date().getSeconds()), count);
}
const incrementThrottled = throttle(increment, 3000);
while (count < 5) {
incrementThrottled();
}
// test result
// 47 1
// 50 2
// 53 3
// 56 4
// 59 5