我有一个observable,它从服务器中提取事件,过滤应用程序类型的事件,然后订阅并将事件分派给一个或多个处理程序来处理。
然后处理程序关闭并对数据库进行异步更新,我发现observable会将事件发生得如此之快以至于更新相互踩踏。我应该期待的。
所以我认为我需要我的处理程序,每个人都使用它自己的observable作为一个队列来处理一个事件并等待一个ack。
所以我的问题是,如何创建一个持续接收消息的observable,并在释放下一条消息之前一次发送一条消息等待确认。
此外,观察者需要感冒。我想,因为我无法传阅信息。
谢谢,
RAIF
答案 0 :(得分:2)
我认为运营商concatMap
做的事情接近你想要的。您可以在此处查看以前的答案,以说明concatMap
的类似用例:
RxJS queueing dependent tasks
它很接近但不完全是你想要的,因为没有等待ACK
信号释放下一个值。相反,concatMap
使用当前执行的'的完成信号。可观察到订阅下一个。如果您的observable包含在db上执行更新的某个地方,那么这些更新将按顺序执行。例如:
function handler (source$) {
// source$ is your source of events from which you generate the update calls
return source$.concatMap(function (event){
return updateDB(event);
})
}
function updateDB(event) {
return Rx.Observable.create(function(observer){
// do the update in the db
// you probably have a success and error handler
// you plug the observer notification into those handlers
if (success) {
// if you need to pass down some value from the update
observer.onNext(someValue);
// In any case, signal completion to allow concatMap to move to next update
observer.onCompleted();
}
if (error) {observer.onError(error);}
})
}
这是专门针对您正在使用的库的通用代码。您可以直接使用运算符fromNodeCallback
或fromCallback
,具体取决于数据库更新功能的API。
同样,请注意在执行当前的observable时可能会有一些缓冲来保持下一个observable,并且缓冲区只能是有限的,所以如果你确实在生产者之间存在显着的速度差异和消费者,或内存限制,你可能想要以不同的方式处理事情。
此外,如果您使用的是RxJS v5,onError
变为error
,onComplete
变为complete
,onNext
变为next
(参见new observer interface)。
最后评论,您的信息流的有损/无损特性是一个与流的热与冷性质不同的概念。对于这两种类型的流,您可以查看illustrated subscription and data flows。