Throttle / Debounce number of calls per second

I'm working with an API that only allows you to make 200 calls per second (1000ms) using a promise request library like request-promise or axios how can you debounce / throttle the requests that are made to a URL / server using rx.js? I noticed a throttle method in the rx documentation, but it won't calculate calls per second.

This is a function that wraps a promise and will queue them to account for a API-rate limit. I'm looking for similar functionality with Rx.

var Promise = require("bluebird")

// http://stackoverflow.com/questions/28459812/way-to-provide-this-to-the-global-scope#28459875
// http://stackoverflow.com/questions/27561158/timed-promise-queue-throttle

module.exports = promiseDebounce

function promiseDebounce(fn, delay, count) {
  var working = 0, queue = [];
  function work() {
    if ((queue.length === 0) || (working === count)) return;
    working++;
    Promise.delay(delay).tap(function () { working--; }).then(work);
    var next = queue.shift();
    next[2](fn.apply(next[0], next[1]));
  }
  return function debounced() {
    var args = arguments;
    return new Promise(function(resolve){
      queue.push([this, args, resolve]);
      if (working < count) work();
    }.bind(this));
  }
}

Answers:

Answer

So I had a similar issue the other day for rate limiting access to a resource. I came across this repo bahmutov/node-rx-cycle. Here is the example in a Plunker Demo I put together to demonstrate this. It takes input from a text input field and prepends it to a <ul>. Each <li> is only prepended every 1000ms, and any others are queued.

// Impure
const textInput = document.querySelector('.example-input');
const prependToOutput = function(item) {
  const ul = document.querySelector('.example-output');
  const li = document.createElement('li');
  li.appendChild(document.createTextNode(item));
  ul.insertBefore(li, ul.firstChild);
};

// Pure
const eventTargetValue = function(ele) { return ele.target.value; };
const textInputKeyUpStream = Rx.Observable
  .fromEvent(textInput, 'keyup')
  .map(eventTargetValue);

// Stream
rateLimit(textInputKeyUpStream, 1000)
  .timeInterval()
  .map(function(ti) { return ti.value + ' (' + ti.interval + 'ms)'; })
  .subscribe(prependToOutput);

Hope this helps.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.