节流/去抖动每秒呼叫次数

时间:2016-02-10 16:59:12

标签: javascript asynchronous rxjs throttling

我正在使用API​​,只允许您使用承诺请求库(如request-promiseaxios每秒拨打200个电话(1000毫秒),您如何去除/限制请求使用rx.js对URL /服务器进行的操作?我注意到rx文档中有throttle method,但它不会计算每秒的调用次数。

这是一个包装承诺的函数,并将它们排队以考虑API速率限制。我正在寻找与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));
  }
}

1 个答案:

答案 0 :(得分:2)

所以前几天我遇到类似的限制访问资源的问题。我遇到了这个回购bahmutov/node-rx-cycle。以下是Plunker Demo中的示例,我将它放在一起来证明这一点。它从文本输入字段获取输入并将其预先设置为<ul>。每个<li>仅每1000毫秒前置一次,其他任何排队等候。

// 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);

希望这有帮助。