【问题标题】:Delayed next call from behaviorSubject when multiple notification - Angular, Rxjs多个通知时延迟来自 behaviorSubject 的下一次调用 - Angular,Rxjs
【发布时间】:2021-04-10 06:46:52
【问题描述】:

在我的 Angular 应用程序中,当数据到来时,我有一个状态 存储在服务中作为BehaviorSubject > 从服务器我调用 next 函数来更新数据并通知所有订阅者。

伪代码:

   ajaxCall_1 -> updateData(response2)
   ajaxCall_2 -> updateData(response2)
   ajaxCall_3 -> updateData(response3)
   ...
    
private data$:Observable<any>;
public updateData(newData){
var currentData = data$.value;
data$.next({...currentData , ...newData})
}

由于很多组件订阅了该 BehaviorSubject,我认为在加载我的应用程序时可能会导致一些性能问题:加载时有很多来自服务器的通知,并且每次调用下一个函数时组件都在渲染。

您认为如果我在 500 毫秒之后将调用延迟到下一个,我会看到性能提升吗? rxjs 延迟下一次调用的方式会是什么?

【问题讨论】:

  • 你需要所有的电话吗?好像经常更新。那么你需要在那里存储最终状态吗?然后你可以使用 switchmap
  • 是的,我需要所有的电话。 switchmap 对我有什么帮助?
  • No SwitchMap 只保留最新的通话 如果你需要所有通话,需要在那里使用 MergeMap。接听所有电话的目的是什么。实际上不知道您的情况。如果是这样,您可能需要在此处更改结构。也许使用队列来排队状态和出列类似的东西
  • 我添加了一些伪代码,现在可能更清楚了吗?
  • 使用unsubscribe 可能对你有帮助

标签: angular rxjs


【解决方案1】:

这是一种您可以决定调用 updateData 函数的频率(例如每秒一次)的方法。

我在这里所做的是将所有调用缓冲一秒钟,然后将缓冲区缩减为单个对象,然后将该对象发送到 updateData。

merge(
  ajaxCall_1,
  ajaxCall_2,
  ajaxCall_3,
  ...
).pipe(
  bufferTime(1000),
  filter(buffer => buffer.length > 0),
  map(bufferedNewData => bufferedNewData.reduce(
    (acc, curr) => ({...acc, ... curr}), {}
  ))
).subscribe(updateData);

另一方面,在第一组调用全部完成之前不显示任何内容可能是有意义的。这可能会使初始负载更可预测。这只是一个微小的变化:

forkJoin([
  ajaxCall_1,
  ajaxCall_2,
  ajaxCall_3,
  ...
]).pipe(
  map(loadNewData => loadNewData.reduce(
    (acc, curr) => ({...acc, ... curr}), {}
  ))
).subscribe(updateData);

【讨论】:

    【解决方案2】:

    性能影响将来自订阅该 BehaviorSubject 的组件,而不是其本身。

    无论如何,您都可以使用delay 运算符来延迟下一个呼叫,如下所示:

    private sub$ = new BehaviorSubject<any>(null);
    public data$ = this.sub$.pipe(delay(500)));
    
    public updateData(newData){
      var currentData = sub$.value;
      sub$.next({...currentData , ...newData})
    }
    

    【讨论】:

    • 延迟不会减少调用次数。它只会推迟他们(全部)。例如,如果您在 10 毫秒和 20 毫秒触发 2 个调用,延迟(500)它们将在 510 毫秒和 520 毫秒发生。您只是在这里将问题转移了 500 毫秒。我认为 OP 正在寻找 debounce、debounceTime、audit、throttle、windowTime、buffer、bufferTime 或 bufferCount(但他必须是选择正确操作员的人,因为他没有描述他想如何解决这个问题)
    • @maxime1992,看来你明白我的问题了,你有答案吗?
    猜你喜欢
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 2012-08-31
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多