繁体   English   中英

RxJs 5 share()运算符如何工作?

[英]How does the RxJs 5 share() operator work?

对于我来说,对于RxJs 5 share()运算符的工作原理并不是100%清楚,请参阅这里的最新文档 Jsbin 这里的问题。

如果我创建一个0到2系列的observable,每个值相隔一秒:

var source = Rx.Observable.interval(1000)
.take(5)
.do(function (x) {
    console.log('some side effect');
});

如果我为这个observable创建了两个订阅者:

source.subscribe((n) => console.log("subscriptor 1 = " + n));
source.subscribe((n) => console.log("subscriptor 2 = " + n));

我在控制台中得到这个:

"some side effect ..."
"subscriptor 1 = 0"
"some side effect ..."
"subscriptor 2 = 0"
"some side effect ..."
"subscriptor 1 = 1"
"some side effect ..."
"subscriptor 2 = 1"
"some side effect ..."
"subscriptor 1 = 2"
"some side effect ..."
"subscriptor 2 = 2"

我认为每个订阅都会订阅相同的Observable,但似乎并非如此! 它就像订阅行为创建了一个完全独立的Observable!

但是如果将share()运算符添加到source observable:

var source = Rx.Observable.interval(1000)
.take(3)
.do(function (x) {
    console.log('some side effect ...');
})
.share();

然后我们得到这个:

"some side effect ..."
"subscriptor 1 = 0"
"subscriptor 2 = 0"
"some side effect ..."
"subscriptor 1 = 1"
"subscriptor 2 = 1"
"some side effect ..."
"subscriptor 1 = 2"
"subscriptor 2 = 2"

没有share()这是我所期望的。

这里有什么, share()运算符是如何工作的? 每个订阅都会创建一个新的Observable链吗?

当您的文档链接似乎是RxJS v4时,请注意使用RxJS v5。 我不记得具体细节,但我认为share操作员经历了一些变化,特别是在完成和重新订阅时,但是不要接受我的话。

回到您的问题,正如您在研究中所展示的那样,您的期望与图书馆设计不符。 Observables懒惰地实例化他们的数据流,具体地在订阅者订阅时启动数据流。 当第二个订阅者订阅相同的observable时,另一个新的数据流被启动,好像它是第一个订阅者一样(所以是的,每个订阅都会像你所说的那样创建一个新的可观察链)。 这就是RxJS术语中创造的冷可观察性,这是RxJS可观察的默认行为。 如果你想要一个observable,它将数据发送给它在数据到达时的订阅者,这就是一个热点可观察者,而获得热点可观察性的一种方法是使用share运算符。

您可以在此处找到插图订阅和数据流: 热门和冷门观察:是否有“热门”和“冷门”运营商? (这对RxJS v4有效,但大多数对v5有效)。

如果满足以下两个条件,则共享会使可观察的“热”:

  1. 订户数> 0
  2. 并且观察结果尚未完成

场景1:订阅者数量> 0,并且在新订阅之前未完成observable

var shared  = rx.Observable.interval(5000).take(2).share();
var startTime = Date.now();
var log = (x) => (value) => { 
    console.log(`onNext for ${x}, Delay: ${Date.now() - startTime} , Value: ${value}`);
};

var observer1 = shared.subscribe(log('observer1')),
    observer2;

setTimeout(()=>{
    observer2 = shared.subscribe(log('observer2'));
}, 3000);

// emission for both observer 1 and observer 2, with the samve value at startTime + 5 seconds
// another emission for both observers at: startTime + 10 seconds

场景2:新订阅前订阅者数量为零。 变得“冷”

 var shared  = rx.Observable.interval(5000).take(2).share();
    var startTime = Date.now();
    var log = (x) => (value) => { 
    console.log(`onNext for ${x}, Delay: ${Date.now() - startTime} , Value: ${value}`);
};

var observer1 = shared.subscribe(log('observer1')),
    observer2;

setTimeout(()=>{
    observer1.unsubscribe(); 
}, 1000);

setTimeout(()=>{
    observer2 = shared.subscribe(log('observer2')); // number of subscribers is 0 at this time
}, 3000);
// observer2's onNext is called at startTime + 8 seconds
// observer2's onNext is called at startTime + 13 seconds

场景3:在新订阅之前完成可观察时。 变得“冷”

 var shared  = rx.Observable.interval(5000).take(2).share();
    var startTime = Date.now();
    var log = (x) => (value) => { 
        console.log(`onNext for ${x}, Delay: ${Date.now() - startTime} , Value: ${value}`);
    };

var observer1 = shared.subscribe(log('observer1')),
    observer2;

setTimeout(()=>{
    observer2 = shared.subscribe(log('observer2'));
}, 12000);

// 2 emission for observable 1, at startTime + 5 secs, and at startTime + 10secs
// 2 emissions for observable 2,at startTime + 12 + 5 secs, and at startTime + 12 + 10secs

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM