关于javascript:为什么我要使用RxJS interval()或timer()轮询而不是window.setInterval()?

Why would I use RxJS interval() or timer() polling instead of window.setInterval()?

用例:每分钟(60000 ms)调用一个函数,该函数调度存储操作以获取项目的lastUpdated状态,该状态在响应和过滤后更新存储,并且更新的存储被视为可观察并显示在看法)。只要Web应用程序处于打开状态(无限期),就需要执行此操作。

当前,我正在使用此:

1
2
3
this.refreshDate = window.setInterval(
  () => this.store.dispatch(new FetchLastUpdate())
, 60000);

当视图被破坏/卸除时,我将间隔删除为:

1
2
3
if (this.refreshDate) {
  clearInterval(this.refreshDate);
}

这是有效/有效的还是麻烦的?

我为什么要使用RxJS轮询策略,例如:

1
2
3
4
5
interval(60000)
  .pipe(
    startWith(0),
    switchMap(() => this.store.dispatch(new FetchLastUpdate()))
   );

1
2
3
4
timer(0, 60000)
  .pipe(
    switchMap(() => this.store.dispatch(new FetchLastUpdate()))
  );

TL; DR:window.setInterval()与RxJS timer() / interval()

结论/答案(为了便于研究):

使用RxJS函数设置时间间隔或执行轮询有很大的好处,这些好处不仅在选定的答案中也在注释中得到了解释,但是结论(通过注释中的讨论)得出的结论是,定义了非常简单的要求在本文开头的"用例"部分中,没有必要使用RxJS,实际上,如果您在程序的任何其他部分未使用RxJS,则不要仅为此目的导入它,但是在我的情况下,我已经在其他地方导入并使用过RxJS。


RxJS的优点:

懒惰

您可以创建自己的Observable,直到调用subscribe都没有任何反应。可观察=纯函数。这给您更多的控制权,更容易的推理,并允许下一点...

可组合性

您可以将interval/timer与其他operators结合在一起,以统一的方式非常轻松地创建自定义逻辑-例如,您可以maprepeatretrytake ...等。查看所有运算符

错误处理

如果发生错误,则您负责调用clearTimeout/clearInterval-Observables将为您处理此问题。导致代码更简洁,内存泄漏错误更少。

当然,您对Observables所做的任何事情也可以在没有Observables的情况下进行-但这不是重点。可观察的物体在这里使您的生活更轻松。

还请注意,interval/timer不是可观察的良好工厂,因为它们不会"等待"异步操作完成(您可能最终会在彼此之间运行多个异步调用)。为此,我倾向于像这样使用deferrepeatWhen

1
2
3
4
defer(() => doAsyncAction())
  .pipe(
    repeatWhen(notifications => notifications.pipe(delay(1234)))
  );


window.setInterval不在乎您的回调状态,尽管已执行了过去的回调,它也会以给定的间隔执行,使其停止并跳过的唯一方法是清除间隔或重新初始化它。

另一方面,基于RxJS Observable的解决方案(intervaltimer)允许您通过管道传递条件运算符(例如takeWhileskipWhile),该条件运算符允许您添加停止符或实现停止符-通过翻转布尔值标志开始逻辑,而不是添加清除间隔然后重新创建的复杂逻辑。

它们是可观察的,您可以在应用程序中全部监听它们,并在其上附加任意数量的监听器。

错误处理也更好,您订阅所有成功,并处理catch回调中的所有内容。