• Limit the number of calls with respect to time.
  • This should execute only once but is getting executed 3 times, this happens in practical scenario, reducing interval to 0 executes it 4 times and increasing it more
const throttle = (func, limit) => {
    let lastFunc
    let lastRan
    return function() {
        const context = this
        const args = arguments
        if (!lastRan) {
            func.apply(context, args)
            lastRan = Date.now()
        } else {
            clearTimeout(lastFunc)
            lastFunc = setTimeout(function() {
                if ((Date.now() - lastRan) >= limit) {
                    func.apply(context, args)
                    lastRan = Date.now()
                }
            }, limit - (Date.now() - lastRan))
        }
    }
}
  • gyan_pelo eg. throttle(1000, 2), To allow only 2 calls within 1 second we need to keep track of when the function ran last time. LastRan and lastFunc (last func is timeout version of given function which has to run) will be global, means outside the returned function from thehigher_order_function . Remember to store this and arguments as the current context and args. If the function didn’t run last time, lastRan is empty then call the function right away with apply else (means it didn’t run last time) then clear the timeout and set the new timeout which runs after checking if current time substracted by lastRan is greater than limit.

Poem

In the coding realm, where lines unfold, A tale of throttle, in memory, I’ll hold.

A senior developer, wise and keen, Crafts a function, a code machine.

Throttle, the guardian of pace, In the dance of time, it finds its space.

Last function, last run, in a delicate ballet, Controls the flow, in a rhythmic display.

Milliseconds ticking, a limit’s decree, Efficiency’s dance, in a code symphony.

Arguments waltz, through the function’s embrace, Throttle’s rhythm, a well-measured grace.

So here’s the verse, to help you see, Throttle’s dance in the lines of esprit.

In the chronicles of code, let memory gleam, As each function hums, in a poetic dream.

rxjs implementation

  /**
   * Returns an Observable that emits only the first item emitted by the source Observable during sequential time windows of a specified duration.
   * @param {Number} windowDuration time to wait before emitting another item after emitting the last item
   * @param {Scheduler} [scheduler] the Scheduler to use internally to manage the timers that handle timeout for each item. If not provided, defaults to Scheduler.timeout.
   * @returns {Observable} An Observable that performs the throttle operation.
   */
  observableProto.throttle = function (windowDuration, scheduler) {
    isScheduler(scheduler) || (scheduler = defaultScheduler);
    var duration = +windowDuration || 0;
    if (duration <= 0) { throw new RangeError('windowDuration cannot be less or equal zero.'); }
    var source = this;
    return new AnonymousObservable(function (o) {
      var lastOnNext = 0;
      return source.subscribe(
        function (x) {
          var now = scheduler.now();
          if (lastOnNext === 0 || now - lastOnNext >= duration) {
            lastOnNext = now;
            o.onNext(x);
          }
        },function (e) { o.onError(e); }, function () { o.onCompleted(); }
      );
    }, source);
  };