Rxjs摆脱了双重订阅

时间:2016-03-24 15:44:02

标签: javascript rxjs

var sourceInit = Rx.Observable.timer(0, 1000)
.do(x => console.log('timer', x))

let source = sourceInit.map(x => x*10)

source.subscribe(x => {
    console.log('x', x)
})

source.subscribe(x => {
    console.log('x2', x)
})

我得到了outpu:

timer 0
x 0
timer 0
x2 0
timer 1
x 10
timer 1
x2 10
timer 2
x2 20
timer 2

我只需要订阅定时器和输出,如下所示:

timer 0
x 0
x2 0
timer 1
x 10
x2 10
timer 2
x 20
x2 20

这个问题的正确方法应该是什么?

我使用这个方法使用主题:

var sourceInit = Rx.Observable.timer(0, 1000)
.do(x => console.log('timer', x))

var source = new Rx.Subject();
sourceInit.subscribe(source)

source.subscribe(x => {
    console.log('x', x)
})

source.subscribe(x => {
    console.log('x2', x)
})

这是正确的,只有一个吗?

1 个答案:

答案 0 :(得分:2)

您遇到的双重订阅问题与Rx observables的冷酷性质有关。默认情况下,Observable是冷的,所以只要你订阅它们,就从头开始。您可以在此处找到有关正在发生的事情的详细说明:Hot and Cold observables : are there 'hot' and 'cold' operators?。这是考虑到Rxjs V4,但它也适用于Rxjs V5。

一个常见的解决方案是使您想要订阅的观察次数“热”几次(主题很热,所以您的解决方案有效)。也就是说,这里没有必要使用主题。要使冷源变热,您可以使用一组运算符,share更常见:

var sourceInit$ = Rx.Observable.timer(0, 1000)
       .share()
       .do(x => console.log('timer', x))

let source$ = sourceInit$.map(x => x*10)

source$.subscribe(x => {
    console.log('x', x)
})

source$.subscribe(x => {
    console.log('x2', x)
})