1
votes

Abonnement imbriqué RxJS

Est-il possible d'éviter abonnement imbriqué dans le code suivant?

this.requestService().subscribe(
      () => this.success(),
      error => {
        const errorDescription = {
          one: 5,
          two: 10
        };
        return this.error(errorDescription).subscribe();
      }
    );

Le deuxième abonnement fait partie du rappel d'erreur de l'Observer. Comment pourrions-nous utiliser par exemple switchMap pour n'avoir qu'un seul abonnement?


1 commentaires

pouvez-vous s'il vous plaît partager le code de la fonction this.error () ?


3 Réponses :


1
votes

Il semble que vous ayez besoin d'un catchError , qui vous permettra remplacez une erreur par un autre flux. Bien que nous devions mettre à jour la gestion des résultats réussie:

this.requestService().pipe(

  // handle success value
  tap(() => this.success()),

  // when an error happens
  catchError(error => {
    const errorDescription = {
      one: 5,
      two: 10
    };

    // we switch to `this.error` stream
    return this.error(errorDescription);
  })
).subscribe(value=>{
  // ...here you'll receive both:
  // events from the requestService()
  // and events from this.error(errorDescription)
});

Voici un article avec un aperçu détaillé de gestion des erreurs dans RxJS

J'espère que cela aide


0 commentaires

0
votes

Voici une idée pour éviter un abonnement "imbriqué". Avec le code que vous avez fourni, c'est le meilleur que je puisse trouver. Si vous avez des questions, faites-le moi savoir et je vous aiderai.

import { of, throwError } from 'rxjs'; 
import { map, switchMap, catchError } from 'rxjs/operators';


// this.requestService().subscribe(
//       () => this.success(),
//       error => {
//         const errorDescription = {
//           one: 5,
//           two: 10
//         };
//         return this.error(errorDescription).subscribe();
//       }
//     );

const error = throwError('oops');
const success = of('success!');
const handleError = (d) => of({one: 5, two: 10}).pipe(
  map(n => n),
  catchError(e => 'could not do 2nd network request')
);

const requestServiceSuccess = success.pipe(
  switchMap(d => of(d)),
  catchError(handleError)
)

const requestServiceFail = error.pipe(
  switchMap(d => of(d)),
  catchError(handleError)
)

// if your first network request succeeds, then you will see success
requestServiceSuccess.subscribe(
  (d) => console.log(d),
  (e) => console.log(e)
)
// if your first network request fails, then you will see your errorDescription
requestServiceFail.subscribe(
  (d) => console.log(d),
  (e) => console.log(e)
)

Vous pouvez coller ceci dans stackblitz pour vérifier les journaux

https://stackblitz.com/fork/rxjs?devtoolsheight=60


1 commentaires

Deux abonnements entraîneront probablement deux demandes, vous devez faire attention ici. Avec of ('success') vous ne le remarquerez pas, mais essayez d'ajouter of ('success'). Pipe (appuyez sur (console.log)) . Il est considéré comme une bonne pratique d'avoir un ou même aucun abonnement dans votre code (aucun abonnement peut être obtenu en utilisant par exemple un tube | async en angulaire ou prêt à l'emploi avec épopées redux).



0
votes

Je le ferais probablement comme ceci:

this.requestService().pipe(catchError(e => {
  const errorDescription = {
      one: 5,
      two: 10
  };
  return this.error(errorDescription).pipe(switchMap(empty())); 
  // the switch to empty will prevent the error going to success
  // consider moving this into the error handler itself.
})).subscribe(
  () => this.success(),
  error => {
    //should never get here.
  }
);

the catchError -> switchMap -> empty est un modèle qui apparaît assez fréquemment dans mon code car mes gestionnaires d'erreurs devraient arrêter la chaîne de traitement davantage souvent qu'autrement.


0 commentaires