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

gar*_*uan 4 javascript frp reactive-extensions-js rxjs

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

  1. 仅在有订阅者时输出事件
  2. 为任何新订阅者提供最新值。

具体的情况是,我需要一个可观察对象,它可以在特定事件发生时进行异步 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
Run Code Online (Sandbox Code Playgroud)

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

let sub1;
sub1 = dataStream.subscribe(x => console.log('sub1', x));
sub1.dispose();
Run Code Online (Sandbox Code Playgroud)

我还希望任何新订阅者在订阅时立即收到最新值。这是我挣扎的地方。如果我这样做...

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

setTimeout( () => {
    sub2 = dataStream.subscribe(x => console.log('sub2', x));
}, 1500)
Run Code Online (Sandbox Code Playgroud)

...直到下一个间隔我才看到console.logfor 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;
Run Code Online (Sandbox Code Playgroud)

据我了解,应该制作dataStream一个hot observable.

但是,在我的测试中,第二个订阅直到下一个时间间隔才收到数据。此外,这会在订阅时引入连接和断开数据流的要求,这是我希望尽可能避免的事情。

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

And*_*ltz 6

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

  • 当你知道怎么做的时候很容易。谢谢。 (2认同)