Trottle 节流函数实现
August 26, 2021JavaScript
虽然节流函数实现这类的文章已经烂大街了,也经常使用源码也看过,但自己亲手实现一边感受又会不一样。当然,此函数并非一气呵成就写出来了,经历了几次使用对比慢慢修正而来。
lodash.trottle 工具方法参数:
参数
func (Function)
: 要节流的函数。[wait=0](number)
: 需要节流的毫秒。[options=](Object)
: 选项对象。[options.leading=true](boolean)
: 指定调用在节流开始前。[options.trailing=true](boolean)
: 指定调用在节流结束后。
返回
(Function)
: 返回节流的函数。
实现
function throttle(func, wait = 0, options = {}) {
const { leading = true, trailing = true } = options;
let timer = null;
let result;
let hasTailCall = false;
const callFunc = function() {
result = func.apply(null, arguments);
}
const cancel = function() {
if (timer) {
clearTimeout(timer);
timer = null;
hasTailCall = false;
}
};
const returnFunc = function() {
if (timer) {
hasTailCall = true;
return result;
}
if (leading) {
callFunc.apply(null, arguments);
}
timer = setTimeout(function() {
if ((!leading || hasTailCall) && trailing) {
callFunc.apply(null, arguments);
}
timer = null;
hasTailCall = false;
}, wait);
return result;
};
returnFunc.flush = function() {
cancel();
callFunc.apply(null, arguments);
return result;
};
returnFunc.cancel = cancel;
return returnFunc;
}
注意点
如何处理返回值:
每次调用都会有返回值,返回值被存储起来了,每次执行完成之后都会更新。
如何处理 this:
TODO
用例
控制头尾执行时机(leading 和 trailing)
let i = 0;
const fn = throttle(
function() {
console.log('this');
return ++i;
},
100,
// 控制执行时机
{ leading: true, trailing: true }
);
var a = { fn };
console.log(fn(123));
console.log(fn(123));
console.log(fn(123));
setTimeout(function() {
console.log(fn(123));
console.log(fn(123));
console.log(fn(123));
}, 1000);
头尾都执行 leading: true, trailing: true
输出:
this
1
1
1
this
this
3
3
3
this
头执行尾不执行 leading: true, trailing: false 输出:
this
1
1
1
this
2
2
2
头不执行尾执行 leading: false, trailing: true 输出:
undefined
undefined
undefined
this
1
1
1
this
头尾都不执行 leading: false, trailing: false 输出:
undefined
undefined
undefined
undefined
undefined
undefined
野生程序猿,专业铲屎官。#Github 账号