如何创建仅在具有订阅者时触发的Observable,并立即向新订阅者提供最新值

时间:2015-09-24 10:32:56

标签: rxjs frp reactive-extensions-js

我正在尝试创建一个流/可观察的...

  1. 仅在有订阅者时输出事件
  2. 为所有新订阅者提供最新价值。
  3. 具体情况是我需要一个observable,它可以在特定事件发生时进行异步API调用,但前提是它只有订阅者。我正在努力避免不必要的API调用。

    我设法创建了一个流,只有拥有这样的订阅者时才会触发......

    let dataStream = Rx.Observable
       .interval(1000) // Fire an event every second
       .singleInstance() // Only do something when we have subscribers
       .startWith(null) // kick start as soon as something subscribes
       .flatMapLatest(interval => SomeAPI.someDataGet()) // get data, returns a promise
    

    这很有效。如果我在console.log(...)方法中SomeAPI.someDataGet,我只会在流有订阅者时看到它触发。我的实现看起来非常好,因为我这样做订阅和取消订阅非常适合与React组件生命周期方法。

    let sub1;
    sub1 = dataStream.subscribe(x => console.log('sub1', x));
    sub1.dispose();
    

    我还希望任何新订阅者在订阅的瞬间获得最新价值。这是我在努力的地方。如果我这样做......

    let sub1, sub2;
    sub1 = dataStream.subscribe(x => console.log('sub1', x));
    
    setTimeout( () => {
        sub2 = dataStream.subscribe(x => console.log('sub2', x));
    }, 1500)
    

    ...直到下一个间隔,我才看到console.log sub2

    如果我的理解是正确的。我需要一个Hot Observable。所以我试图像这样创建一个流......

    let dataStream = Rx.Observable
       .interval(1000) // Fire an event every second
       .singleInstance() // Only do something when we have subscribers
       .startWith(null) // kick start as soon as something subscribes
       .flatMapLatest(interval => SomeAPI.someDataGet()) // get data
       .publish() // Make this a hot observable;
    

    根据我的理解,应将dataStream设为hot observable

    但是,在我的测试中,第二个订阅在下一个间隔之前仍然不会收到数据。另外,这会引入在订阅时连接和断开dataStream的要求,如果可能的话我想避免这种情况。

    我是RxJS的新手,如果我误解了这里发生的事情,我不会感到惊讶。

1 个答案:

答案 0 :(得分:4)

而不是.publish(),请使用.shareReplay(1)