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