Home > Software engineering >  Timeout Operator of RXJS not working as expected
Timeout Operator of RXJS not working as expected

Time:11-30

I have to do polling until I get the response as completed. But I also want to do polling only for 2mins and prevent infinite polling for this I am using timeout operator but that doesn't seem to work.

     interval(5000)
     .pipe(

    startWith(0),
    switchMap(() => this.someService.getQueueJob(jobId)),
    takeUntil(this.stopPolling),
    timeout(2*60000)
  )
  .subscribe((res) => {
    this.jobStatus = res.attributes.status;
    if (this.jobStatus === 'Completed') {
      this.fileUploadStatus = 'success';
      this.stopPolling.next();
    } else if (this.jobStatus === 'Failed') {
      this.fileUploadStatus = 'error';
      this.stopPolling.next();
    }
  });

Also I need to throw error when timeout happens and inform the user.

CodePudding user response:

The timeout will be reset everytime there is an emission. So for each emission of the interval and the corresponding this.someService.getQueueJob() its reset. You could accomplish your requirement with an additional takeUntil with the timer function.

Also

  1. You say 2 mins timeout in the question, but the code only has a min.?
  2. As mentioned by @Chris in the comments, you could replace the interval(5000) startWith(0) combo with timer(0, 5000).
timer(0, 5000).pipe(
  switchMap(() => this.someService.getQueueJob(jobId)),
  takeUntil(this.stopPolling),
  takeUntil(timer(120000))
).subscribe(
  ...
);

Edit 1: Replace interval(5000) startWith(0) with timer(0, 5000)

CodePudding user response:

You can use timer at startup for timeout:

// set time for timeout
timer(2 * 60000).pipe(
  // trow error when timer emit event after 2 minutes
  map(() => { throw new TimeoutError() }),
  // put startWith operator to start before timer emit timeout event
  startWith(0),
  // switch to polling timer for every 5 second
  switchMap(() => timer(0, 5000)),
  // get date from http
  switchMap(() => this.someService.getQueueJob(jobId)),
  // stop manually the polling
  takeUntil(this.stopPolling),
).subscribe(
  (data) => console.log(data),
  (error) => {
    if (error instanceof TimeoutError)
      console.log('time out')
    else
      console.log('http error')
  }
);
  • Related