How to create an RXjs RetryWhen with delay and limit on tries

前端 未结 2 1505
迷失自我
迷失自我 2020-12-02 20:50

I am trying to make an API call (using angular4), which retries when it fails, using retryWhen. I want it to delay for 500 ms and retry again. This can be achieved with this

相关标签:
2条回答
  • 2020-12-02 21:21

    You need to apply the limit to the retry signal, for instance if you only wanted 10 retries:

    loadSomething(): Observable<SomeInterface> {
      return this.http.get(this.someEndpoint, commonHttpHeaders())
        .retryWhen(errors => 
          // Time shift the retry
          errors.delay(500)
                // Only take 10 items
                .take(10)
                // Throw an exception to signal that the error needs to be propagated
                .concat(Rx.Observable.throw(new Error('Retry limit exceeded!'))
        );
    

    EDIT

    Some of the commenters asked how to make sure that the last error is the one that gets thrown. The answer is a bit less clean but no less powerful, just use one of the flattening map operators (concatMap, mergeMap, switchMap) to check which index you are at.

    Note: Using the new RxJS 6 pipe syntax for future proofing (this is also available in later versions of RxJS 5).

    loadSomething(): Observable<SomeInterface> {
      const retryPipeline = 
        // Still using retryWhen to handle errors
        retryWhen(errors => errors.pipe(
          // Use concat map to keep the errors in order and make sure they
          // aren't executed in parallel
          concatMap((e, i) => 
            // Executes a conditional Observable depending on the result
            // of the first argument
            iif(
              () => i > 10,
              // If the condition is true we throw the error (the last error)
              throwError(e),
              // Otherwise we pipe this back into our stream and delay the retry
              of(e).pipe(delay(500)) 
            )
          ) 
      ));
    
      return this.http.get(this.someEndpoint, commonHttpHeaders())
        // With the new syntax you can now share this pipeline between uses
        .pipe(retryPipeline)
    }
    
    0 讨论(0)
  • 2020-12-02 21:22

    Use

    .retry(3)
    

    Repeats the source observable sequence the specified number of times or until it successfully terminates.

    https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/retry.md

    0 讨论(0)
提交回复
热议问题