ngrx轮询在订阅

时间:2017-12-01 16:27:51

标签: javascript angular rxjs ngrx

上下文

我在相关应用程序中使用以下库:Angular 4.x,ngrx 4.x,rxjs 5.4.x

在我的应用程序中,我能够从websocket获取一些数据但是对于一些我必须打一个RESTful api。我通过ngrx在多个组件之间共享数据。现在我根据创建,更新和删除等事件重新获取数据。

我不希望对数据进行多次并发修改,但我确实需要一种方法来手动或自动确保我的客户端状态与服务器匹配。我想进行修补客户端状态的乐观更新,而不是在相关的状态片段上进行全数据刷新的成本。

RxJs方法

如果我没有使用ngrx,那么我可能只会有一个服务暴露出类似下面的observable,它会缓存api调用的最新结果并与所有订阅共享。它会偶尔更新结果,但前提是它有订阅者。



const interval = 1000;
let counter = 0;

// setup a timer that executes immediately and on a timer
let call = Rx.Observable.timer(0, interval)
  // make the fake async call
  .switchMap(() => Rx.Observable.of(counter++).delay(100))
  .do(x => console.log('call', x))
  // cache latest value and share the value with all subscribers
  .publishReplay(1, interval)
  // only connect (aka make the call) if there are more than 1 subscribers
  .refCount();

// convenience method for simulation
function subscribe(name, take) {
  call.take(take).subscribe(
    x => { console.log(name, x); },
    null,
    () => { console.log(`${name} completed`) }
  );
}

// observers
subscribe('first', 1);
subscribe('second', 2);
window.setTimeout(() => {
  subscribe('third', 3);
}, 3500);

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>
&#13;
&#13;
&#13;

问题

我不确定如何用ngrx模仿这种相同的行为,因为ngrx会处理对自身的订阅。在许多方面,它将订阅与源断开连接。以下是我已经考虑过的一些想法:

  • 也许有一种方法我可以躲过store.select,但我认为我必须在reducers中定义的效果和状态之间定义明确的关系。
  • 我可以让每个页面/组件注册它感兴趣的内容,并以这种方式跟踪订阅,但这实际上只是重复订阅。
  • 我可以为位于ngrx前面的每个状态切片设置投影,并以某种方式触发相关效果,但这看起来很棘手并且可能令人费解。
  • 辞掉工作,以宠物石为生。

问题

只有在相关数据片段上有活跃订阅时,如何在一个时间间隔内提取数据才能更新ngrx存储?

1 个答案:

答案 0 :(得分:0)

我认为我不明白100%的情况。但我想我会做这样的事情:

  • 在我的商店中,有一些属性可以跟踪是否正在监视一段数据(布尔值)
  • 当加载监视该数据的组件时,将该值设置为true的事件设置
  • 当组件不再存在时,使用ngOnDestroy将值设置为false
  • 有一个ngrx效果,可以监视该值是否发生变化。如果值更改为true,则开始从服务器获取数据,并在获得响应时,调度事件以更新存储中的数据,并以一定的间隔继续执行此操作。将setInterval或timer的返回值保存在可以在其他地方访问的变量中,可以作为类的属性。
  • 如果值变为false,则不同的ngrx效果正在侦听该操作,将获取持有计时器/间隔的变量,并清除/取消订阅。可以和takeUntil一起撰写这些内容