rxjs速率限制(每秒请求数)和并发性
我正试图找出如何在rxjs中编写一个速率限制器。用于访问大多数API(twitter、facebook等),如果开箱即用的方法不支持,我假设可以编写一个调度器。例如,highland.js就有。我不想放弃任何项目,如窗口,样品等rxjs速率限制(每秒请求数)和并发性,rxjs,Rxjs,我正试图找出如何在rxjs中编写一个速率限制器。用于访问大多数API(twitter、facebook等),如果开箱即用的方法不支持,我假设可以编写一个调度器。例如,highland.js就有。我不想放弃任何项目,如窗口,样品等 var source = Rx.Observable.create(function (observer) { // queue of requests _.each(requests, function(r) { observer.onNext(r)
var source = Rx.Observable.create(function (observer) {
// queue of requests
_.each(requests, function(r) {
observer.onNext(r);
});
observer.onCompleted();
// Any cleanup logic might go here
return function () {
console.log('disposed');
}
})
// what goes here, if built in (e.g. 2 requests per 2 seconds or 15 request per 15 minutes)
// SHOULD ONLY RUN
var subscription = source.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
编辑1:
考虑一下这样的事情,使用令牌桶算法,仍然很粗糙,但是
Rx.Observable.prototype.tokenBucket=函数(选项,调度器){
功能时间(){
返回新日期().getTime();
}
变量桶={
容量:选项。容量| |无穷大,
左:选项。容量,
最后:time(),
TokensPrinterval:options.TokensPrinterval,
间隔:options.interval
};
//var BUCKET=\合并(defaultOptions,options);
控制台日志(桶);
var source=这个,
scheduler=scheduler | |(scheduler=Rx.scheduler.timeout);
返回Rx.Observable.create(函数(观察者){
var d1=源.subscribe(函数(mainValue){
返回油门(主值);
});
功能节流阀(x,令牌){
if(BUCKET.capacity==无穷大){
返回观测器onNext(x);
}//返回x;
//每S毫秒要添加的令牌数=(r*S)/1000。
var self=铲斗;
var now=time();
var deltaMS=Math.max(现在-self.last,0);
self.last=现在;
var dripAmount=deltaMS*(self.tokensPerInterval/self.interval);
self.left=Math.min(self.left+dripAmount,self.capacity);
如果(自左<1){
var区间=数学区间((1-自左)*自区间);
scheduleWithRelative(间隔,函数(s,i){
回油节流阀(x);
});
}否则{
self.left-=令牌| | 1;
console.log('calling');
返回观测器onNext(x);
}
}
返回函数(){
d1.处置();
log('disposed tokenBucket');
};
});
};
var start=力矩();
var源=接收可观测范围(1,20)
.tokenBucket({容量:2,tokensPerInterval:2,间隔:2000})
var subscription=source.subscripte(
函数(x){console.log('onNext:%s',x);addToDom(x);},
函数(e){console.log('onError:%s',e);},
函数(){console.log('onCompleted');});
函数addToDom(x){
var ul=document.getElementById('c');
var li=document.createElement('li');
li.innerHTML=x+'-'+moment().diff(开始,'seconds')+'s ago';
ul.儿童(li);
}
如果您只想删除其间发生的事件,可以使用windowWithTimeOrCount+throttleFirst:
var subscription = source
//Splits the events into 15 minute windows
.windowWithTimeOrCount(900000 /*15 minutes*/, 15)
//Stops us from receiving more than one window in 15 minutes
.throttleFirst(900000 /*15 minutes*/)
//Flatten the observable
.concatAll()
.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
工作示例(控制台中的输出):
var source=Rx.Observable.generateWithRelativeTime(
0,
函数(x){返回x<1000;},
函数(x){返回x+1;},
函数(x){return x;},
函数(x){返回Math.floor(Math.random()*100);});
来源
.windowWithTimeOrCount(1000,3)
.节流阀第一(1000)
.concatAll()
.subscribe(console.log.bind(console))代码>
如果您只想删除其间发生的事件,可以使用windowWithTimeOrCount+throttleFirst:
var subscription = source
//Splits the events into 15 minute windows
.windowWithTimeOrCount(900000 /*15 minutes*/, 15)
//Stops us from receiving more than one window in 15 minutes
.throttleFirst(900000 /*15 minutes*/)
//Flatten the observable
.concatAll()
.subscribe(
function (x) { console.log('onNext: %s', x); },
function (e) { console.log('onError: %s', e); },
function () { console.log('onCompleted'); });
工作示例(控制台中的输出):
var source=Rx.Observable.generateWithRelativeTime(
0,
函数(x){返回x<1000;},
函数(x){返回x+1;},
函数(x){return x;},
函数(x){返回Math.floor(Math.random()*100);});
来源
.windowWithTimeOrCount(1000,3)
.节流阀第一(1000)
.concatAll()
.subscribe(console.log.bind(console))代码>
如果您不想丢失任何通知,可以使用缓冲区或它的一种变体(使用time/count/time或count)。
它基本上将通知组合在一个数组中,并在以下情况下转发该数组:
- 可观察的通知
- 计时器过期
- 已达到通知数
- 以上各项的结合
因此,您可以将通知缓冲在一个数组中,每分钟只接收一次,或者在100个通知到达时接收一次
如果您不想丢失任何通知,可以使用缓冲区或它的一种变体(带有time/count/time或count)。
它基本上将通知组合在一个数组中,并在以下情况下转发该数组:
- 可观察的通知
- 计时器过期
- 已达到通知数
- 以上各项的结合
因此,您可以将通知缓冲在一个数组中,每分钟只接收一次,或者在100个通知到达时接收一次
我在我的个人项目中遇到了一个非常类似的问题,并决定将一个可重用的解决方案作为npm包发布
与此不同的是,它不会强制延迟每个事件。我在我的个人项目中遇到了一个非常类似的问题,并决定将一个可重用的解决方案作为npm包发布
与之不同的是,它不会对每个事件强制延迟。我现在只看generateWithRelativeTime
。我不想在处理队列中丢弃任何内容。真的只是想防止超过特定api的速率限制。如果您不想删除任何元素,还可以查看controlled
。@dre,如果您不想删除任何事件,您想如何处理额外的事件?等下一次开门?取决于可能开始堆叠的下一个应用程序。或者您只是在某个时间间隔ping端点?是的,基本上是一个处理队列,所以您不想删除任何内容,但必须遵守速率限制。@dre请参阅我的备选方案。我想它可能更接近你想要的。我现在只看generateWithRelativeTime
。我不想在处理队列中丢弃任何内容。真的只是想防止超过