当两个订阅者订阅一个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));
控制台记录以下内容:
'哎' '订户1 = 0' '哎' '订户2 = 0' '哎' '订阅者1 = 1' '哎' '订阅者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));
控制台记录:
'哎' '订户1 = 0' '订阅者2 = 1' '哎' '订户1 = 0' '订阅者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));
日志:
'来自',1'来自',2'来自',3' --- 0 ---',3 '来自',1' --- 1 ---',1 '来自',2'来自',3'来自',1'来自',2' --- 2-- - ',2'来自',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()
,也会记录from数据的方式与上一次尝试的方式完全相同,而不是share()
(从1到2从3记录3次,每个用户1次) )。
那么,这些例子中的观察点之间有什么区别?
如何在第二种情况下共享数据?
答案 0 :(得分:3)
使用Rxjs 4,您应该只看到from 1 from 2 from 3
一次。但是,您只有一个过滤器日志记录。 Rx.Observable.from(array)
同步发出序列。因此,执行s.filter(v => v % 3 === 0).subscribe(v => console.log('---0---', v));
时,您的s
可观察量已经完成。你可以在这里看到:[jsfiddle]。输出是:
from 1
from 2
from 3
---0--- 3
在Rxjs 5中,share
运算符现在在结束时重新启动源并且新订阅者订阅。在第二个过滤器,重新启动s
。因此,您在源序列生成过程中进行了三次。
为了说服您,将同步序列转换为异步序列:jsfiddle。你现在应该得到,这是你所期望的:
from 1
---1--- 1
from 2
---2--- 2
from 3
---0--- 3
奇怪的是,migration guide中没有记录这一点。但是,您可以找到一些有关更改动机的信息here和here(简而言之,您会得到改进的repeat
和retry
语义。)
也就是说,您仍然可以使用share
拥有Rxjs 4 publish().refCount()
运算符。但如前所述,您的第二个过滤器将看不到数据,因为源已经完成。见这里:jsfiddle。