Comment créer un RxJS Retywhen avec delay et limit sur tries

j'essaie de faire un appel API (en utilisant angular4), qui se réessaie quand il échoue, en utilisant retryWhen. Je veux qu'il retarde de 500 ms et rejoue. Ceci peut être réalisé avec ce code:

loadSomething(): Observable<SomeInterface> {
  return this.http.get(this.someEndpoint, commonHttpHeaders())
    .retryWhen(errors => errors.delay(500));
}

mais cela va continuer à essayer pour toujours. Comment puis-je limiter à, disons 10 fois?

Merci!

12
demandé sur Mouneer 2017-07-04 20:12:28

2 réponses

vous devez appliquer la limite au signal de Ré-essai, par exemple si vous ne vouliez que 10 ré-essais:

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

certains des commentateurs ont demandé comment s'assurer que la dernière erreur est celle qui est lancée. La réponse est un peu moins nette mais pas moins puissante, il suffit d'utiliser l'un des opérateurs de carte aplati (concatMap, mergeMap, switchMap) pour vérifier à quel index vous êtes.

Remarque: l'Utilisation de la nouvelle RxJS 6 pipe syntaxe pour l'avenir correction d'épreuves (également disponible dans les versions ultérieures de 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)
}
27
répondu paulpdaniels 2018-08-14 04:46:13

Utiliser

.retry(3)

répète la séquence source observable le nombre de fois spécifié ou jusqu'à ce qu'elle se termine avec succès.

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

-4
répondu Valery Lyatsevich 2017-07-04 17:25:29