对rxjs订阅进行解块和缓冲

对rxjs订阅进行解块和缓冲,rxjs,rxjs5,Rxjs,Rxjs5,我有一个消息队列处理器,它将消息提供给服务 q.on(“消息”,(m)=>{ 服务创建(m) .然后(()=>m.ack()) .catch(()=>n.nack()) }) 该服务使用RxJS Observable和订阅debounceTime()这些请求 类服务{ 构造函数(){ this.subject=新主题() 此.subject.debounceTime(1000) .subscribe({req,resolve,reject})=> someOtherService.doWork

我有一个消息队列处理器,它将消息提供给服务

q.on(“消息”,(m)=>{
服务创建(m)
.然后(()=>m.ack())
.catch(()=>n.nack())
})
该服务使用RxJS Observable和订阅
debounceTime()
这些请求

类服务{
构造函数(){
this.subject=新主题()
此.subject.debounceTime(1000)
.subscribe({req,resolve,reject})=>
someOtherService.doWork(需求)
。然后(()=>resolve())
.catch(()=>拒绝())
)
}
创建(请求){
返回新承诺((解决、拒绝)=>
这个。主题。下一个({
请求,
决定
拒绝
})
)
}
}

问题是,只有取消公告的请求才能获得ackd/nackd。如何确保订阅同时解析/拒绝其他请求
bufferTime()
为我提供了一部分方法,但它不会在每次调用
next()

时重置超时持续时间。您当前使用的
debounceTime
操作符可用于创建一个可观察的对象,该对象可以通知
buffer
当前缓冲区应关闭的时间

然后,
buffer
将发出一组在去抖动时接收到的消息,您可以随意处理它们:

this.subject=新主题();
const closingNotifier=this.subject.debounceTime(1000);
this.subject.buffer(closingNotifier.subscribe)(消息=>{
const last=messages.length-1;
messages.forEach({req,resolve,reject},index)=>{
如果(索引==最后一个){
/*不管你在做什么,现在,带着这个脱口而出的信息*/
}否则{
/*无论您需要如何处理被忽略的消息*/
}
});
});

对于那些正在寻找RXJS 6解决方案的人,我创建了一个自定义操作符,其行为类似于前面的答案中的
debounce()
+
buffer()

我称之为
bufferDebounce
,带有类型推断的Typescript中的代码片段如下:

从'rxjs'导入{Observable,OperatorFunction}
从“rxjs/operators”导入{buffer,debounceTime}
类型BufferDebounce=(debounce:number)=>OperatorFunction;
常量bufferDebounce:bufferDebounce=debounce=>source=>
新的可观察对象(观察者=>
source.pipe(缓冲区(source.pipe(debounceTime(debounce))).subscribe({
下一(x){
观察员:下一个(x);
},
错误(err){
观察者错误(err);
},
完成(){
observer.complete();
},
}),
);

在本例中,您可以测试其行为,以检查这是否适合您

您可以使用
缓冲区
和基于
debounceTime
构建的关闭通知程序。有关基本机制,请参见。这将给你所有的排放量在谴责的持续时间内,你可以做任何你想做的。既然这个解决方案合并了两个流,你会如何在这里合并这个方法?你可以不合并。通知缓冲区很常见,它是通知程序的
debounceTime
而不是
auditTime
。我可以很快给你回信;我知道你现在的意思了…尝试过这种方法,似乎很有效。那么为什么没有
bufferDebounce
操作员呢?我犯了一个错误,做了
buffer(100)
,我只是偶然发现,我永远都是每隔100毫秒得到一个空数组!我本以为
缓冲区(100)
如果为空,则不会发出任何信息。我假设这个版本在10秒钟内没有收到任何消息时不会运行回调。我想这是因为其他人会要求
bufferAudit
bufferThrottle
,等等。它们中的任何一个都可以由
buffer
和通知程序构建。我很高兴我发现了
buffer(0)
在太迟或混乱之前不是一个好主意!有点像当你真的想放
shareReplay(1)
;-)时使用
shareReplay()