RxJ合并流

时间:2017-03-16 17:11:45

标签: rxjs rxjs5

我期待合并流并刷新所有订阅者。

对于函数编程目的,concat不会更新当前的observable,我不知道正确的方法。

这就是我希望事情发生的方式:

var observable = Rx.Observable.from(['stream1']);
var subscription = observable.subscribe(
    function(x) {
        console.log('Next: ' + x);
    },
    function(err) {
        console.log('Error: ' + err);
    },
    function() {
        console.log('Completed');
    });
observable.concat(Rx.Observable.from(['stream2']));

此代码仅读取第一个流然后转到完成。 当concat创建一个我不想要的新Observable,因为我已经订阅了第一个。

什么是正确的方法,因为我甚至无法进入第一个观察者?

谢谢!

1 个答案:

答案 0 :(得分:2)

你想要做的事情并非如此,但你基本上有两种选择,都涉及Subject的使用:

1)手动发送数据

const obs$ = Rx.Observable.of("stream1");
const subj$ = new Rx.Subject();

Rx.Observable.merge(obj$, subj$)
    .subscribe(
        x => console.log('Next: ' + x),
        x => console.log('Error: ' + x),
        () => console.log('Complete')
    );

subj$.next("stream2");
subj$.next("stream3");

但是:在这种情况下,永远不会调用完整,因为Subject永远不会自行完成 - 所以如果你需要你的complete - 处理程序触发后,您必须在最后添加手册subj$.complete();

2)通过主题进行多播

const obs$ = Rx.Observable.of("stream1");
const subj$ = new Rx.Subject();

subj$.subscribe(
    x => console.log('Next: ' + x),
    x => console.log('Error: ' + x),
    () => console.log('Complete')
);

obs$.subscribe(x => subj$.next(x));
const obs2$ = Rx.Observable.of("stream2");
obs2$.subscribe(x => subj$.next(x));

在这种情况下,Subject基本上将充当“代理”,它只会传播数据,但不会传播错误或完整的触发器。

这两种解决方案都不是很“好” - 但也许你可以更好地概述你的用例,我确信它有一个适当的解决方案,不涉及任何复杂的解决方法。

如果您只是希望有一种方法可以连续提供永久Observable的数据,您应该使用BehaviorSubject - 它的工作方式是,您可以在其上发布数据并在其中订阅它同一时间:

class Service {
    public data$ = new BehaviorSubject(someInitialDataOrNull);

    public getData() {
        makeSomeHttpCall()
            .subscribe(data => data$.next(data));
    }
}

class Component {
    constructor() {
        theService.data$.subscribe(data => console.log(data));
    }
}

以下是指向BehaviorSubject的旧文档的链接(它基本上仍然与onNext现在next所期望的方式相同,等等...)