ngrx 轮询以在订阅时刷新数据

byg*_*ace 5 javascript rxjs ngrx angular

语境

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

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

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

RxJs 方法

如果我不使用 ngrx,那么我可能只有一个服务,它会暴露一个如下所示的可观察对象,它会缓存 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);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

问题

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

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

仅当相关数据切片上有活动订阅时,如何才能按时间间隔提取数据以更新 ngrx 存储?

Bre*_*ing 0

我不认为我 100% 理解发生了什么。但我想我会做这样的事情:

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