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

msa*_*prz 12 javascript rxjs typescript rxjs5 rxjs6

使用案例:每分钟调用一个函数(60000毫秒),调度存储操作以获取lastUpdated项目的状态,在响应和过滤时,更新存储,更新的存储被读取为可观察的并显示在视图中).只要Web应用程序处于打开状态(如此无限期),就需要进行此操作.

目前,我正在使用这个:

this.refreshDate = window.setInterval(
  () => this.store.dispatch(new FetchLastUpdate())
, 60000);
Run Code Online (Sandbox Code Playgroud)

当视图被销毁/卸载时,我删除间隔如下:

if (this.refreshDate) {
  clearInterval(this.refreshDate);
}
Run Code Online (Sandbox Code Playgroud)

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

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

interval(60000)
  .pipe(
    startWith(0),
    switchMap(() => this.store.dispatch(new FetchLastUpdate()))
   );
Run Code Online (Sandbox Code Playgroud)

要么

timer(0, 60000)
  .pipe(
    switchMap(() => this.store.dispatch(new FetchLastUpdate()))
  );
Run Code Online (Sandbox Code Playgroud)

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


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

使用RxJS函数来设置间隔或执行轮询有很大的好处,这些好处在选定的答案中也可以在注释中解释,但是(通过评论中的讨论)得出的结论是,对于" 本帖子开头的用例 "部分,没有必要使用RxJS,事实上如果你没有在你的程序的任何其他部分使用RxJS,请不要仅为此导入它,但在我的情况下,我有已导入并在其他地方使用RxJS.

m1c*_*4ls 14

RxJS的优势:

怠惰

你可以创建你的Observables,直到你打电话subscribe什么都没发生.Observable =纯函数.这为您提供了更多控制,更容易推理,并允许下一点...

组合性

您可以组合interval/timer与其他operators创建自定义的逻辑很容易在统一的方式-例如,你可以map,repeat,retry,take...等看到所有的运营商

错误处理

如果出现错误,您负责调用clearTimeout/clearInterval- Observables正在为您处理此问题.从而产生更清晰的代码更少的内存泄漏错误.

当然,你使用Observables做的任何事情,你也可以没有Observables - 但这不是重点.Observables可以让您的生活更轻松.


还要注意,interval/timer这不是用于轮询的良好可观察工厂,因为它们不会"等待"您的异步操作完成(最终可能会有多个异步调用相互运行).为此我倾向于使用deferrepeatWhen喜欢这样:

defer(() => doAsyncAction())
  .pipe(
    repeatWhen(notifications => notifications.pipe(delay(1234)))
  );
Run Code Online (Sandbox Code Playgroud)


Ash*_*war 8

window.setInterval 不关心你的回调状态,不管过去回调的执行状态如何,它都会在给定的间隔内执行,并且让它停止和跳过的唯一方法是清除间隔或重新初始化它。

在另一方面,RxJS可观测基础的解决方案(intervaltimer)让你管条件运算符(takeWhileskipWhile例如),它允许您通过只是翻转一个布尔标志,而不是加入复杂的逻辑添加停止或实施停止起动逻辑清除间隔,然后重新创建它。

它们是可观察的,您可以在整个应用程序中收听它们,并为其附加任意数量的侦听器。

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

  • @Adeel 您是否有示例代码来执行您的建议?据我了解,即使在最后一个完成之前,也无法阻止 setInterval 再次运行回调? (2认同)