Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我要使用RxJS interval()或timer()轮询而不是window.setInterval()?_Javascript_Typescript_Rxjs_Rxjs5_Rxjs6 - Fatal编程技术网

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

Javascript 为什么我要使用RxJS interval()或timer()轮询而不是window.setInterval()?,javascript,typescript,rxjs,rxjs5,rxjs6,Javascript,Typescript,Rxjs,Rxjs5,Rxjs6,用例:每分钟(60000毫秒)调用一个函数,该函数调度存储操作以获取项目的lastUpdated状态,该状态在响应和筛选后更新存储,更新的存储被读取为可观察状态并显示在视图中)。只要web应用程序处于打开状态,这种情况就需要发生(所以无限期) 目前,我正在使用: this.refreshDate = window.setInterval( () => this.store.dispatch(new FetchLastUpdate()) , 60000); 当视图被销毁/卸载时,我删除

用例:每分钟(60000毫秒)调用一个函数,该函数调度存储操作以获取项目的
lastUpdated
状态,该状态在响应和筛选后更新存储,更新的存储被读取为可观察状态并显示在视图中)。只要web应用程序处于打开状态,这种情况就需要发生(所以无限期)

目前,我正在使用:

this.refreshDate = window.setInterval(
  () => this.store.dispatch(new FetchLastUpdate())
, 60000);
当视图被销毁/卸载时,我删除间隔,如下所示:

if (this.refreshDate) {
  clearInterval(this.refreshDate);
}
这是有效的还是麻烦的

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

interval(60000)
  .pipe(
    startWith(0),
    switchMap(() => this.store.dispatch(new FetchLastUpdate()))
   );


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


结论/答案(为了便于研究):
使用RxJS函数设置间隔或执行轮询有很大的好处,这些好处在注释中也有解释,但是(通过注释中的讨论)可以得出结论,对于本文开头的“用例”部分中定义的非常简单的需求,没有必要使用RxJS,事实上,如果您没有在程序的任何其他部分使用RxJS,请不要仅为此导入RxJS,但是在我的情况下,我已经在其他地方导入并使用了RxJS。

window.setInterval
不关心您的回调状态,它将以给定的间隔执行,而不管过去回调的执行状态如何,让它停止和跳过的唯一方法是清除间隔或重新初始化它

另一方面,RxJS基于可观察的解决方案(
间隔
计时器
)允许您使用管道条件运算符(
takeWhile
skipWhile
),它允许您通过翻转布尔标志添加停止或实现停止-启动逻辑,而不是添加清除间隔然后重新创建间隔的复杂逻辑

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

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

RxJS的优势:

懒惰

您可以创建您的可观察对象,直到调用
subscribe
为止,一切都不会发生。可观察=纯函数。这给了你更多的控制,更容易的推理,并允许下一点

可组合性

您可以将
间隔/计时器
与其他
操作符
以统一的方式组合起来创建自定义逻辑-例如,您可以
映射
重复
重试
获取
。。。等等

错误处理

如果发生错误,您负责调用
clearTimeout/clearInterval
——可观察对象将为您处理此问题。导致更干净的代码更少的内存泄漏错误

当然,任何你用可观察物做的事情,你也可以不用可观察物做——但这不是重点。可观察到的东西让你的生活更轻松


还要注意的是,
interval/timer
对于轮询来说不是很好的可观察工厂,因为它们不会“等待”异步操作完成(最终可能会导致多个异步调用互相运行)。为此,我倾向于使用
defer
repeatWhen
如下:

defer(() => doAsyncAction())
  .pipe(
    repeatWhen(notifications => notifications.pipe(delay(1234)))
  );

错了!如果
window.setInterval
有一个基于XHR的回调,可以使用async/await使其等待。Ramda和其他库都是多余的。@Adeel您有一个示例代码来执行您的建议吗?据我所知,即使在最后一次回调完成之前,也无法阻止setInterval再次运行回调?谢谢您的回复。在@m1ch4ls的帖子之前,我没有看过你的帖子,我对此发表了评论。但基本上,你是对的,下次轮到我投票时,我一定会考虑这些问题,因为我以前没有考虑过。方便、干净地访问这些操作员以及更灵活的错误处理是非常有利的。阅读本文的其他案例/人员将从这些观点中获益,但我不认为这些观点对我的具体案例有何益处。我将在下一条评论中粘贴我的其他评论中的原因。另外,为了澄清为什么我没有看到这个用例的任何好处,我做了另一条评论:如果要求每分钟只调用一个函数,那么就没有必要创建一个完整的(干净的)逻辑。我不需要任何错误处理,因为我的
FetchLastUpdate()
操作处理它自己的所有错误,存储处理它自己的错误,以及异步HTTP调用。不过,自动清理是有益的,这样我就不必调用
clearInterval()
,但我不确定这是否值得调用RxJS函数来避免这种情况。尽管我可能高估了这一点。@Chris这里是我编的一个快速示例,请注意我在这个示例中获取随机用户的位置。我可以将其包装在try/catch中,清除我的间隔,并执行错误处理。希望这能有所帮助。我认为
FetchLastUpdate
不会持续超过
60
秒,因此使用
switchMap
似乎有些过分,我宁愿使用
setInterval
,这似乎足够您使用了case@OlivierBoiss好吧,这就是我一直以来的想法,但我想我会寻求其他更有经验的意见。至于switchMap,你是对的,tap可能会更好。此外,添加
rxjs
将增加你的js包大小,因此如果你在其他地方不需要它,你可以跳过它并使用
setInterval
@OlivierBoissé这是真的,尽管出于你提到的原因(在其他地方使用),它不适用于我。谢谢:)谢谢
defer(() => doAsyncAction())
  .pipe(
    repeatWhen(notifications => notifications.pipe(delay(1234)))
  );