javascripttimingthrottlingdebouncing

Can I throttle a function without dropping function calls in JS?


I need a function to have certain amount of time between one function call and another, very similar to what a throttle would do, but I need all the function calls to be attended.

Let me explain:

Let's imagine we have a throttle of 10 seconds on a function foo, and an event that calls foobar. The event is fired 3 times, one every 5 seconds. Only the first one and the last one would be attended while the one in the middle would be ignored.

Normal throttle:

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

What I need is that the event is always listened, but 10 seconds after the previous one.

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

Any ideas? I thought about throttle and also debouncer but none of them would fit what I need to do.


Solution

  • This is pretty simple to do. Just create an array of function objects, and pull the oldest one off every 10 seconds and execute it.

        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'))

    You could add some logic to clear the interval when the queue is empty, and start it up again fresh when a new item comes in so that the first call always happens immediately if it's not waiting. But I leave that an exercise for you.