我正在使用一个调用我实现的函数的框架。我希望将此函数的参数转换为Observable,并通过一系列Observers发送。我以为我可以使用一个主题,但它的表现并不像我预期的那样。
为了澄清,我有类似下面的代码。我认为下面的Option 1
会起作用,但到目前为止,我正在寻找Option 2
,这似乎不是惯用的。
var eventSubject = new Rx.Subject();
var resultSource = eventSubject.map(processEvent);
var subscription = resultSource.subscribe(
function(event) {
console.log("got event", event);
},
function(e) {
log.error(e);
},
function() {
console.log('eventSubject onCompleted');
}
);
// The framework calls this method
function onEvent(eventArray) {
var eventSource = Rx.Observable.from(eventArray);
// Option 1: I thought this would work, but it doesn't
// eventSource.subscribe(eventSubject);
// Option 2: This does work, but its obviously clunky
eventSource.subscribe(
function(event) {
log.debug("sending to subject");
eventSubject.onNext(event);
},
function(e) {
log.error(e);
},
function() {
console.log('eventSource onCompleted');
}
);
}
答案 0 :(得分:3)
正如Brandon已经解释的那样,将eventSubject订阅到另一个observable意味着将eventSubjects onNext,onError和onComplete订阅到onNext,onError和onComplete上的observable。从您的示例中,您似乎只想订阅onNext。
第一个eventSource完成/错误后,你的主题完成/ errros - 你的eventSubject正确地忽略了后续eventSoures对它发出的任何进一步的onNext / onError。
有多种方法可以只订阅任何eventSource的onNext:
仅手动订阅onNext。
resultSource = eventSubject
.map(processEvent);
eventSource.subscribe(
function(event) {
eventSubject.onNext(event);
},
function(error) {
// don't subscribe to onError
},
function() {
// don't subscribe to onComplete
}
);
使用只处理订阅eventNeource onNext / onError的运算符。这就是布兰登建议的。 请记住,这也订阅了eventSources onError,您似乎不希望这样做。
resultSource = eventSubject
.mergeAll()
.map(processEvent);
eventSubject.onNext(eventSource);
使用不为eventSources onError / onComplete调用eventSubjects onError / onComplete的观察者。您可以简单地将eventSubjects onComplete覆盖为脏黑客,但最好是创建一个新的观察者。
resultSource = eventSubject
.map(processEvent);
var eventObserver = Rx.Observer.create(
function (event) {
eventSubject.onNext(event);
}
);
eventSubject.subscribe(eventObserver);
答案 1 :(得分:2)
只是当您将整个Subject
订阅到一个可观察对象时,您最终会向该主题订阅该可观察对象的onComplete
事件。这意味着当观察完成时,它将完成您的主题。因此,当您获得下一组事件时,他们什么也不做,因为主题已经完成。
一个解决方案正是您所做的。只需将onNext
事件订阅到主题。
第二个解决方案,可以说更像“rx like”,将您的传入数据视为可观察的可观察数据,并使用mergeAll展平此可观察流:
var eventSubject = new Rx.Subject(); // observes observable sequences
var resultSource = eventSubject
.mergeAll() // subscribe to each inner observable as it arrives
.map(processEvent);
var subscription = resultSource.subscribe(
function(event) {
console.log("got event", event);
},
function(e) {
log.error(e);
},
function() {
console.log('eventSubject onCompleted');
}
);
// The framework calls this method
function onEvent(eventArray) {
var eventSource = Rx.Observable.from(eventArray);
// send a new inner observable sequence
// into the subject
eventSubject.onNext(eventSource);
}