【问题标题】:RXJS - How to repeat a subscription after some periodsRXJS - 如何在一段时间后重复订阅
【发布时间】:2020-02-12 14:29:24
【问题描述】:

我想每 15000 毫秒重复一次相同的 REST 调用订阅(轮询)。我试过这个:

foo() {
    return this.httpClient.get('/rest')
    .pipe(
      delay(15000),
      repeat(),
    );
}

//...
this.foo().subscribe(() => console.log('HEY'));

除了延迟 15000 毫秒后的第一次发射外,效果很好。那么,如何在不等待第一次延迟的情况下获得相同的结果呢?

【问题讨论】:

    标签: angular rxjs httpclient polling


    【解决方案1】:

    您可以使用interval 调用创建一个可在预定义延迟后重复发射的可观察对象。然后你只需要mergeMap那个可观察到你的网络调用。

    foo() {
        return interval(15000).pipe(
          mergeMap(() => this.httpClient.get('/rest')),
        );
    }
    
    //...
    this.foo().subscribe(() => console.log('HEY'));
    

    【讨论】:

    • 间隔也会延迟第一次通话
    • interval 延迟第一次发射,你需要使用 timer(0,15000),作为练习,这里 switchMap 是更好的操作符
    • @bryan60 这应该是答案
    • @bryan60 哎呀,那我搞错了。您应该将其发布为答案...除了,为什么switchMap 更好?我们不知道 OP 想对调用结果做什么。
    • 这将每 15 秒发出一个新请求,即使请求花费的时间超过 15 秒。在计算 15 秒之前,它不会等待请求完成
    【解决方案2】:

    您可以将要延迟的值存储在一个局部变量中,该变量初始化为 0,然后在第一次调用后更新。

    foo() {
        let delayBy = 0;
        return this.httpClient.get('/rest')
        .pipe(
          delay(delayBy),
          tap(() => delayBy = 15000),
          repeat()
        );
    }
    

    编辑:Bryan 对 timer(0, 15000) 的建议比这更好

    【讨论】:

      【解决方案3】:

      没试过,但应该可以。

      与其他答案的主要区别在于它会等待请求完成,然后再等待 15 秒并再次轮询。

      const mockRequest = () =>
        of("mockedRequest").pipe(
          // simulate network latency
          delay(500)
        );
      
      const myRequest = () => {
        return mockRequest().pipe(
          switchMap(res =>
            concat(of(res), timer(DELAY_BETWEEN_REQUESTS).pipe(ignoreElements()))
          ),
          repeat()
        );
      };
      

      现场演示:https://stackblitz.com/edit/rxjs-5fg2ov?file=index.ts

      【讨论】:

        猜你喜欢
        • 2017-12-13
        • 1970-01-01
        • 2021-10-17
        • 2019-08-20
        • 2020-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多