当两个订阅者订阅一个observable时:
let s = Observable.interval(1000).take(2).do(x => console.log('hey'));
s.subscribe(n => console.log('subscriber 1 = ' + n));
s.subscribe(n => console.log('subscriber 2 = ' + n));
控制台记录以下内容:
‘hey’
‘subscriber 1 = 0’
‘hey’
‘subscriber 2 = 0’
‘hey’
‘subscriber 1 = 1’
‘hey’
‘subscriber 2 = 1’
使用.share():
let s = Observable.interval(1000).take(2).do(x => console.log('hey')).share();
s.subscribe(n => console.log('subscriber 1 = ' + n));
s.subscribe(n => console.log('subscriber 2 = ' + n));
控制台日志:
‘hey’
‘subscriber 1 = 0’
‘subscriber 2 = 1’
‘hey’
‘subscriber 1 = 0’
‘subscriber 2 = 1’
因此,我设法向超过1个订阅者共享相同的数据.
执行以下测试:
let s = Observable
.from([-1, 0, 1, 2, 3])
.filter(v => v > 0)
.do(v => console.log('from', v));
s.filter(v => v % 3 === 0)
.subscribe(v => console.log('---0---', v));
s.filter(v => v % 3 === 1)
.subscribe(v => console.log('---1---', v));
s.filter(v => v % 3 === 2)
.subscribe(v => console.log('---2---', v));
日志:
‘from’, 1 ‘from’, 2 ‘from’, 3 ‘—0—‘,3 ‘from’, 1 ‘—1—‘,1
‘from’, 2 ‘from’, 3 ‘from’, 1 ‘from’, 2 ‘—2—‘, 2 ‘from’, 3
再次,我使用share():
let s = Observable
.from([-1, 0, 1, 2, 3])
.filter(v => v > 0)
.do(v => console.log('from', v))
.share();
s.filter(v => v % 3 === 0)
.subscribe(v => console.log('---0---', v));
s.filter(v => v % 3 === 1)
.subscribe(v => console.log('---1---', v));
s.filter(v => v % 3 === 2)
.subscribe(v => console.log('---2---', v));
});
尽管我使用了share(),但是来自数据的记录方式与上一次尝试的方式完全相同,没有share()(从1到2从3记录3次,每个用户1次).
那么,这些例子中的观察点之间的区别是什么?
如何在第二种情况下共享数据?
解决方法:
使用Rxjs 4,您应该从1到2从3只看到一次.但是,您只有一个过滤器日志记录. Rx.Observable.from(array)同步发出它的序列.因此,当s.filter(v => v%3 === 0).subscribe(v => console.log(‘— 0 —‘,v));执行后,您的可观察性已经完成.你可以在这里看到:[jsfiddle].输出是:
from 1
from 2
from 3
---0--- 3
在Rxjs 5中,共享操作符现在在结束时重新启动源并且新订户订阅.在第二个过滤器,s重新启动.因此,您在源序列生成过程中进行了三次.
为了说服你,将你的同步序列变成一个异步序列:jsfiddle.你现在应该得到,这是你所期望的:
from 1
---1--- 1
from 2
---2--- 2
from 3
---0--- 3
奇怪的是,migration guide中没有记录这一点.但是,您可以找到有关here和here更改动机的一些信息(简而言之,您可以获得改进的重复和重试语义).
也就是说,您仍然可以使用publish().refCount()来拥有Rxjs 4 share运算符.但如前所述,您的第二个过滤器将看不到数据,因为源已经完成.见:jsfiddle.