【问题标题】:setInterval or rxjs interval which one to use?setInterval 或 rxjs 间隔使用哪一个?
【发布时间】:2021-11-09 14:06:42
【问题描述】:

关于这个主题有很多讨论,但我仍然无法弄清楚我需要将哪一个用于我的用例。我有一个方法需要每 3 秒调用一次以获取更新的库存详细信息。

ngOnInit() {
  
  this.getUpdatedStock(); // to get data while loading page for first time
  this.interval = setInterval(()=> {
    this.getUpdatedStock();
   },3000)

}

而 getUpdatedStock() 在渲染数据之前调用服务并进行一些操作。

getUpdatedStock(){
   this.stockService.getStockData().subscribe((data)=> {
   this.latestStock = data ;
   // few lines of code to highlight table headers based on response
})}

正如 setInterval() 所期望的那样,如果响应有延迟,并且在收到最后一个响应后 3 秒后调用没有发生,那么请求就会堆积起来。然后我发现以下线程解释了 rxjs 方法的使用

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

还有一些建议不要在该用例中使用 rxjs,因为它可能会增加包大小。现在我正在考虑将哪一个用于我的用例。我不希望在收到上一个请求的响应之前发生呼叫,并且在收到响应后应该 3 秒。是否可以使用 setInterval() 本身或者我必须使用 rxjs 。如果我必须使用 rxjs timer() 或 interval() 可以有人告诉我如何做到这一点,因为我没有直接调用服务。我正在调用触发服务调用并完成数据操作的方法。

【问题讨论】:

    标签: angular timer rxjs setinterval


    【解决方案1】:

    一个 RxJS 解决方案:

    RxJS 确实让这类事情变得非常容易。此外,您大多只是根据您使用的内容来增加捆绑包的大小。我将把审议留给你,并告诉你我会用 RxJS 实现它。

    在这里,我将静音计时器与您的 getStockData 合并。计时器只是确保合并的 observable 不会在 3 秒之前完成。如果getStockData 花费的时间超过 3 秒,则忽略计时器。

    然后我永远重复这个。

    ngOnInit() {
      
      merge(
        this.stockService.getStockData(),
        timer(3000).pipe(filter(_ => false))
      ).pipe(
        repeat(),
      ).subscribe({
        next: this.updateStock
      });
    
    }
    
    updateStock(data){
      this.latestStock = data;
      // few lines of code to highlight table headers based on response
    }
    

    更新#1:

    解释过滤器:

    timer(3000) 将在 3 秒后发出数字 0。我们实际上不希望计时器发出任何东西。它只是作为可观察对象长度的下限。因此,为了阻止它发出任何值,我们通过过滤所有内容来使其静音。

    filter(_ => false) 表示“无论值是什么,都不允许它通过”。

    timer(3000).pipe(filter(_ => false)) 不会发出任何内容,然后发送complete 事件。

    这里的效果是,即使this.stockService.getStockData() 需要 1 秒才能完成。 merge 仍将等待 2 秒(总共 3 秒),然后合并流完成。另一方面,如果 this.stockService.getStockData() 完成时间超过 3 秒,则合并流将在 this.stockService.getStockData() 完成后立即完成。

    解释重复:

    repeatWhen(a => a) 实际上与仅使用repeat() 相同。我使用第一个是因为我认为你必须重复一个数字,但你没有。

    Repeat 完全按照听起来的样子。当源流完成时,它只是重新启动它。 repeatWhen 为您提供了对该过程的一些细粒度控制,但鉴于您所描述的内容,您不需要它。


    更新 #2:

    你是说延迟 3 秒后重复吗?

    每当 stockService.getStockData() 完成时,这将等待 3 秒,然后再次调用 stockService.getStockData()

    这意味着如果对stockService.getStockData() 的第一次调用需要 5 秒,那么第二次调用将在 8 (5 + 3) 秒发生。

    ngOnInit() {
    
      this.stockService.getStockData().pipe(
        repeatWhen(co => co.pipe(
          delay(3000)
        )),
      ).subscribe({
        next: this.updateStock
      });
    
    }
    
    updateStock(data){
      this.latestStock = data;
      // few lines of code to highlight table headers based on response
    }
    

    【讨论】:

    • 非常感谢您的回复。如果您不介意,能否请您解释一下代码。
    • :) 我已经在答案中解释了一点。如果您有任何问题,也许我可以帮助解释更多。
    • 我无法理解 filter 和 repeatWhen here 的用法。因此,如果您能解释这段代码中真正发生的事情,那将会很有帮助。我对 rxjs 没有太多想法。对不起。正在努力学习
    • @ani 抱歉回复缓慢。我试图解释更多。
    • 感谢您的详细回答。但是如果方法需要超过 3 秒,我想检查第二种情况。实际上,服务调用需要 5 秒才能完成。所以在这里我希望在收到响应后 3 秒触发下一个服务调用。
    猜你喜欢
    • 2021-02-16
    • 2021-07-03
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 2017-01-06
    • 2016-05-28
    相关资源
    最近更新 更多