Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用RxJS限制异步请求_Javascript_Node.js_Rxjs - Fatal编程技术网

Javascript 使用RxJS限制异步请求

Javascript 使用RxJS限制异步请求,javascript,node.js,rxjs,Javascript,Node.js,Rxjs,我需要向服务发送大量数据。我每分钟可以发送的项目有一个限制,每个请求发送的项目不超过350个,因此我将数据拆分为多个页面,并尝试使用Observable来限制请求: const maxItemsPerRequest = 350; const interval = Math.round(60 /*seconds*/ / maxPerMinute * 1000); const pages = Math.ceil(totalItems / maxItemsPerRequest); let obser

我需要向服务发送大量数据。我每分钟可以发送的项目有一个限制,每个请求发送的项目不超过350个,因此我将数据拆分为多个页面,并尝试使用
Observable
来限制请求:

const maxItemsPerRequest = 350;
const interval = Math.round(60 /*seconds*/ / maxPerMinute * 1000);
const pages = Math.ceil(totalItems / maxItemsPerRequest);

let observable = Observable.interval(interval).take(pages);

observable.subscribe(async page => {
  const items = await getItems(page, maxItemsPerRequest);
  await this.sendData(items);
});
getItems
sendData
可能需要一段时间才能完成,因此可能会在第二分钟内超过请求限制,例如(如果在第一分钟内创建的请求需要60秒以上才能完成)


如何确保订阅者在发送新请求之前,在上一个请求完成后至少等待
间隔
毫秒?

基本上,您不希望在
订阅
中执行操作,因为您无法控制它何时完成。相反,您希望使其成为链的一部分,延迟将从上一次调用结束时开始

例如,您可以这样做:

let observable = Observable.range(pages)
  .concatMap(page => getItems(page, maxItemsPerRequest)
    .concatMap(items => this.sendData(items))
    .delay(interval) // delay the emission from this Observable
  )
  .subscribe(console.log);

下面是一个序列,它在
sendData()
完成时使用Subject to信号,并根据该信号调节间隔

下面的演示间隔为500毫秒,但sendData会导致1000毫秒的延迟。如果将sendData的内部延迟更改为100,则流将以500毫秒的间隔继续

console.clear()
const nextPage=新接收行为主体(true);
常数间隔=500
常数页=8
const getItems=()=>Rx.Observable.of([1,2,3])
const sendData=()=>{
返回可观察到的接收值('x')
.延迟(1000)
}
让可观测=接收可观测间隔(间隔)
.节气门(i=>nextPage)
.take(页)
.concatMap(p=>getItems())
.concatMap(items=>sendData(items))
.do(x=>nextPage.next())
const start=Date.now()
const show=(val)=>console.log(val,Date.now()-start)
可观察。订阅(显示)

相当不错。唯一的问题是,您有
sendData
给出的延迟加上时间间隔。是的,这就是OP想要的:订阅者在上一个请求完成后等待至少间隔毫秒,然后再发送新请求?事实上,我注意到在发布我的答案之后。尽管如此,他想要什么,他需要什么……但是,60秒的等待是一段很长的时间——也许延迟是累加的无关紧要。