我可以在不放弃JS中函数调用的情况下限制函数吗?

时间:2020-01-29 18:06:59

标签: javascript timing throttling debounce

我需要一个函数在一个函数调用与另一个函数调用之间有一定的时间,这与节流阀的操作非常相似,但我需要所有函数调用都应得到照顾。

让我解释一下:

假设我们在函数foo上有10秒的油门,还有一个调用foobar的事件。 该事件被触发3次,每5秒触发一次。只有第一个和最后一个会参加,而中间的一个会被忽略。

普通油门:

[event]--5s--[event]--5s--[event]
[foo]---------10s---------[foo]

我需要的是该事件总是被监听,但距上一个事件已过10秒。

[event]--5s--[event]--5s--[event]
[foo]----------10s--------[foo]---------10s--------[foo]

有什么想法吗?我想到了节流阀和去抖器,但它们都不适合我需要做的事情。

2 个答案:

答案 0 :(得分:1)

这很简单。只需创建一个函数对象数组,然后每10秒拉出最早的函数对象并执行即可。

    const queue = []
    
    function rateLimit(fn) {
      queue.push(fn)
    }
    
    setInterval(() => {
      const nextFn = queue.shift() // remove the first function, and return it.
      if (nextFn) nextFn() // execute the first function if it exists.
    }, 1000) // Your interval in milliseconds. Set to 1s for testing.
    
    
    rateLimit(() => console.log('A'))
    rateLimit(() => console.log('B'))
    rateLimit(() => console.log('C'))

您可以添加一些逻辑来清除队列为空时的时间间隔,并在有新项目进入时重新启动它,以便在不等待时始终立即进行第一个调用。但是我为您保留了一项练习。

答案 1 :(得分:0)

如果有人感兴趣,我使用Alex Wayne的答案,并添加了一些逻辑以更好地控制他所说的间隔。

const queue = []
var intervalExecution

function rateLimit(fn) {
  queue.push(fn)
  if (queue.length && !intervalExecution) {
    intervalExecution = setInterval(() => {
      const nextFn = queue.shift()
      if (nextFn) {
        nextFn()
      } else {
        clearInterval(intervalExecution)
        intervalExecution = undefined
      }
    }, 1000)
  }
}

rateLimit(() => console.log('test'))
rateLimit(() => console.log('test'))
rateLimit(() => console.log('test'))
rateLimit(() => console.log('test'))