Search code examples
ecmascript-6rxjsrxjs5

Rxjs: Repeat an Ajax Call Every X Seconds, but Wait for the Last One to Complete


I would like to query an API every x seconds when subscribing to an autorefresher Observable, making sure that the last request has completed before sending another one.

let autoRefresher = new Observable().exhaustMap(() => Observable.defer(() => {
    return someService.returningAPromise();
}).timeout(refreshIntervalInMs).repeat());

Is there a better way to do this? How could I update the refresh interval without creating a new observable each time?


Solution

  • I'd do it like this:

    import {Observable} from 'rxjs';
    
    function doRequest() {
      if (Math.random() < 0.25) {
        return Observable.of('HTTP Response').delay(3000);
      } else {
        return Observable.of('HTTP Response');
      }
    }
    
    let autoRefresher = Observable.timer(0, 1000)
      .exhaustMap(doRequest)
      .subscribe(response => {
        console.log(response);
      });
    

    See live demo: http://plnkr.co/edit/7HAib10r6Vdl1x2U2wFS

    This randomly makes 3s delay. Operator timer() periodically emits a value. Then exhaustMap() subscribes to the preceding Observable and ignores all Observables emitted until the current one completes. So timer() is emitting values but these are ignored by exhaust().

    Btw, note that I'm using TypeScript.