从使用 switch 构建的可观察对象接收完成通知

Receiving done notifications from observables built using switch

在下面的示例中,foobar 接收数据,但在 bar 完成时忽略。 foobaz 完成时完成,这不是我想要的行为。

var baz = Rx.Observable.interval( 50 ).take( 10 );

var foo = baz
    .select(function (x) { 
        var bar = Rx.Observable.range(x, 3);
        return bar;
    })
    .switch();

是否有 switch 的变体或我可以使用的技术使新创建的 foo observable 具有与 bar 相同的生命周期?也就是说,我希望 foobar 完成的情况下完成。


解决方案:

var baz = Rx.Observable.interval( 50 ).take( 10 );

var foo = baz
    .select(function (x) { 
        var bar = Rx.Observable.range(x, 3).materialize()
        return bar;
    })
    .switch()
    .dematerialize();

onCompleted() 根据定义是终端情况,所以不,您不能直接在外部 Observable.

中接收 onCompleted()

根据您需要如何使用 onCompleted,您有几个选项。

您可以使用 .tapOnCompleted().finally() 来处理流终止的副作用:

var foo = Rx.Observable.range(0, 3)
.select(function (x) { 
    return Rx.Observable.range(x, 3)
           .tapOnCompleted(function(){/*Apply side effect*/});
          //Or .finally()

})
.switch();

或者您需要 materialize 内部流来处理值:

var foo = Rx.Observable.range(0, 3)
.select(function (x) { 
    var bar = Rx.Observable.range(x, 3)
    .materialize();
    return bar;
})

.switch()

foo.subscribe(function(x) {
  if (x.kind == 'N') {
    process(x.value);
  } else if (x.kind == 'C') { /*Do something else*/}
});

请注意,在您给出的示例中,当 switch 发生时,Observable 将不会完成,只有最后一个会完成,因为后续值的输入速度太快。

如果所有序列在完成之前都应 运行,则应使用 concatAll() 而不是 switch()