BFE.devAI解答 - JavaScript 代码题
4. 手写throttle()
下面是一种可行的throttle()实现方式:
function throttle(func, delay) { let lastTime = 0 let timeout return function(...args) { const currentTime = Date.now() if (currentTime - lastTime >= delay) { func.apply(this, args) lastTime = currentTime } else { clearTimeout(timeout) timeout = setTimeout(() => { func.apply(this, args) lastTime = currentTime }, delay - (currentTime - lastTime)) } }}
实现方式分析:
lastTime
表示上一次函数调用的时间戳,初始为0,表示第一次调用也不会被延迟执行。timeout
为setTimeout返回的定时器ID,用于在定时器执行前清除未被执行的函数调用。- 返回一个函数接收任意参数。
- 在函数内部,首先获取当前时间戳
currentTime
。 - 若
currentTime
距离上一次调用的时间间隔大于等于delay
,执行函数调用,并更新lastTime
。 - 若时间间隔小于
delay
,则清除之前设置的定时器,重新设置一个新的定时器,在delay - (currentTime - lastTime)
后调用函数并更新lastTime
。
以上代码可能有一些缺陷,比如某些情况下可能会出现积攒多次调用而只执行一次的问题。但是在大多数情况下是可行的,能够满足题目的要求。在实际应用中,也可以使用Lodash等库中提供的成熟的throttle()实现。