Fermer

janvier 12, 2022

Introduction aux observables (RxJS)—Partie 2


Dans le deuxième article en deux parties, nous aborderons les abonnés et le processus d'abonnement à un observable.

Ceci est le deuxième d'une série d'articles en deux parties. Dans le premier articlenous avons couvert les bases des observables, des observateurs et de RxJS. Veuillez commencer par là si vous ne l'avez pas déjà fait.

kitten-in-grass" title="kitten-in-grass"/></p data-recalc-dims=

Crédit photo : Andriyko Podilnyk sur Unsplash.

Observateurs contre abonnés

Vous avez peut-être remarqué que nous utilisons indifféremment les observateurs et les abonnés. Les observateurs et les abonnés sont-ils les mêmes ? Sinon, comment sont-ils liés les uns aux autres ? Examinons en examinant aux observateurs d'abord.

Observers

Pour souscrire à un observable, nous appelons la méthode subscribe() de l'observable et passons un observer ou un next() rappel comme argument.

Qu'est-ce qu'un observateur dans RxJS ?

Un observateur est un objet de type observateur avec les next , error et méthodes complètes :

export interface Observer<T> {
  suivant: (valeur: T) => void;
  erreur: (err: tout) => void;
  complete: () => void;  
}

Profitons de cette occasion pour examiner de plus près chacune des méthodes d'observation.

Next

La méthode de l'observateur next définit comment traiter les données envoyées par l'observable.

const observer = {
  next: (value) => {
    
  }
};

La fonction observable envoie des données à l'observateur en appeler la méthode next de l'observateur et passer les données en argument. L'appel de la fonction de rappel de l'observateur pour envoyer des données est appelé émission de données.

const myObservable$ = new Observable(observer => {
  
  const valeur = Math.random();
  
  
  observateur.next(value); 
});

Error

L'observateur erreur La méthode gère l'erreur envoyée par l'observable.

const observer = {
  error: err => 
};

La fonction observable avertit l'observateur si une erreur se produit en appelant la méthode error de l'observateur et en la transmettant les informations d'erreur.

const myObservable$ = new Observable(observer => {
  
  
  
  
  observateur.error(error);
});

Par exemple :

pikachu$ = nouveau Observable(observer => {  
  fetch('https://pokeapi.co/api/v2 /pokemon/pikachu')  
    .then(réponse => réponse.json() )  
    .puis(pikachu => {
      observateur.suivant(pikachu);
      observateur.complet();  
    })  
    .prise(err =>  observateur.erreur(err)) 
});

Complet

L'observateur complete() callback spécifie l'action à entreprendre lorsque l'observable a terminé de produire et d'émettre des données.

const observer = {
  complete: () => console.log('Vous avez épuisé toutes les voyelles.' )
};

La fonction observable permet à l'observateur de savoir qu'il a fini de produire et d'envoyer des données en appelant le rappel complete() de l'observateur. C'est le cas lorsque l'observable a une séquence de valeurs d'une longueur finie, par exemple, émettant les éléments d'un tableau qui a cinq éléments.

const voyelles$ = new[19659013]Observable(observer => {
  
  const voyelles = ['a', 'e ', 'i', 'o', 'u'];

  
  pour ( let lettre de voyelles) {
    observateur.suivant(valeur);
  }
 
  
  observateur.complete();
});

Voyons ce qu'est un abonné et comment il se rapporte à l'observateur.

Subscribers

RxJS utilise la classe d'abonné pour gérer les abonnements. C'est une classe interne destinée à l'usage de la bibliothèque.

Nous savons déjà que nous passons un objet observer ou un rappel next à la méthode subscribe() . Voici le petit plus : la méthode subscribe() convertit l'objet observer ou le rappel next en un objet subscriber.

La classe d'abonné implémente l'interface d'observation. Par conséquent, un objet abonné a les méthodes nexterror et complete.

En outre, un objet abonné garde une trace de si l'observable est arrêté et fournit une logique telle que :

  • next ne peut pas être exécuté une fois que l'observable s'est trompé ou terminé.
  • nexterror ou complete ne peut pas être appelé après unsubscribe.
  • unsubscribe est appelé sur error ou complete pour libérer les ressources utilisées par l'abonnement et l'observable.

Isn' C'est super que la librairie RxJS nous apporte ces garanties ?! 🦄

Récapitulons ce que nous avons appris sur les observables jusqu'à présent 🐾🐾🐇 :

  • Un observable produit des données et les envoie à ses observateurs.
  • Nous informons l'observable qu'un observateur souhaite recevoir des données en s'abonnant à l'observable et passant dans l'observateur.
  • Dans le code, un observateur est représenté par un objet avec les méthodes nexterror et complete. Ces méthodes définissent comment traiter les valeurs et les notifications envoyées par l'observable.
  • Pour commencer à recevoir des données d'un observable, nous nous abonnons à l'observable et transmettons l'objet observateur.
  • En interne, RxJS convertit l'observateur en abonné. objet. L'abonné fournit une logique supplémentaire pour gérer l'exécution correcte des rappels d'observateur. Il efface également les ressources lorsque l'observable se termine, ou a une erreur, ou si l'observateur se désabonne.

Exécuter un Observable

Comme avec les fonctions, la fonction observable est inerte. Il définit comment produire les données (observable à froid) ou se referme sur le code qui produit les données (observable à chaud). Mais la fonction observable n'émet aucune valeur tant qu'elle n'est pas exécutée.

Nous exécutons une fonction avec la parenthèse() :

functionName(parameter)

Alors que nous exécutons indirectement une fonction observable en appelant la méthode subscribe() de l'observable :

const subscription = voyelles$
  .subscribe(valeur => console.log(valeur))[19659019];

La méthode subscribe() appelle la fonction de l'observable qui produit et émet des données. Ainsi, l'abonnement à un observable déclenche un flux de données entre l'observable et l'observateur.

Examinons de plus près la méthode subscribe().

S'abonner à un observable

Le La méthode subscribe() orchestre quelques tâches importantes pour l'observable dans les coulisses :

  1. Elle accepte un objet observateur ou des fonctions de rappel en tant que paramètres.
  2. Elle convertit l'observateur ou fonctions de rappel vers un objet SafeSubscriber. SafeSubscriber étend la classe d'abonné qui à son tour étend la classe d'abonnement.
  3. Il exécute la fonction observable et passe l'abonné comme argument. à l'objet abonné.
  4. Et il retourne l'objet abonné, qui, comme nous l'avons mentionné précédemment, est de type abonnement.

Regardons le subscribe() signatures de méthode ensuite.

Les signatures de la méthode subscription()

La méthode de souscription a quelques signatures :

  1. La première signature prend un observateur partiel comme argument.
subscribe(observer ?: Partiel<Observateur<T>>): Abonnement;[19659032]Nous passons un objet qui implémente l'interface d'observation. Il est courant de simplement passer un objet littéral avec les méthodes nexterror et complete.

import { from  } from  'rxjs';
const voyelles$ = from(['a' 'e', 'i', 'o', 'u']);

voyelles$.subscribe({
  next: x => console.log('La voyelle suivante est : ', x),
  erreur: err => console.error('Une erreur s'est produite', err) 
  complete: () => console.log('Il n'y a plus de voyelles.')[19659031]});

La méthode subscribe() attend un type d'observateur partialelle n'a donc pas à inclure les trois méthodes. Nous pouvons omettre les méthodes dont nous n'avons pas besoin.

voyelles$.subscribe({
  next: x => console.log('Voyelle suivante : ', x) 
  complete: () => console.log('Plus de valeurs dans la séquence.')   
});

Nous pourrions appeler subscribe() sans passer aucun paramètre puisque le paramètre est facultatif. Par exemple, au lieu de réagir aux valeurs émises par l'observable, nous pourrions vouloir effectuer un effet secondaire en utilisant l'opérateur tap.

Dans l'exemple ci-dessous, nous enregistrons simplement les voyelles dans le console du navigateur à l'aide d'un opérateur tap(). Cela illustre que l'appel de subscribe() appelle effectivement la fonction observable, même si nous ne passons pas d'observateur ou de rappel suivant.

const voyelles$
  .tuyau(robinet(console.log);)  
  .[19659050]subscribe();





  1. La deuxième signature pour subscribe() prend la fonction de rappel next().
subscribe ](suivant: (valeur: T) => vide): Abonnement;

Lorsque nous voulons uniquement traiter la valeur des données, nous pouvons simplement passer le rappel next() :

voyelles$.subscribe (
  voyelle => console.log('Voyelle suivante : ', voyelle)
) ; 

Plutôt qu'un objet avec la méthode suivante :

voyelles$.subscribe(
  { next : console de voyelles. log('Voyelle suivante : ', voyelle) }
) ;
  1. Passer plusieurs fonctions de rappel à subscribe() est obsolète.

Il existe des signatures pour subscribe() qui prennent les next()error() et complete() fonctions de rappel comme paramètres.

La signature suivante nous permet d'omettre certaines des fonctions de rappel et de passer undefined ou null à la place. Cependant, il est obsolète.

subscribe(next?: ((value: T) => void) | null, erreur?: ((error: any) => void) | null, complete? : (() => void) | null): Abonnement; 

La documentation RxJS conseille de passer plusieurs rappels dans un objet observateur plutôt que de passer les rappels en tant qu'arguments séparés. Veuillez vous référer à la docs pour plus d'informations.

Certaines observables produisent un ensemble fini de valeurs, mais d'autres peuvent continuer à produire des valeurs à l'infini. Que faire si nous ne voulons plus recevoir de données d'un observable ? Ne vous inquiétez pas, l'observable ne sera pas offensé. En fait, les observables sont sympas et savent annuler les abonnements gracieusement. 🐳

Comme nous l'avons mentionné précédemment, l'appel de subscribe() sur un observable renvoie un objet subscription. L'objet d'abonnement a une méthode appelée unsubscribe() qui nous permet de nous désabonner de l'observable.

Se désabonner d'un observable fait les deux choses suivantes :

  • Arrête l'exécution de la fonction observable, arrêtant ainsi l'observable de produire ou d'émettre plus de données.
  • Efface les ressources utilisées par l'abonnement et exécute la fonction de démontage de l'observable.

Rappelez-vous que la fonction observable peut renvoyer une fonction contenant la logique de démontage. La méthode subscribe() ajoute la fonction de suppression de l'observable à l'abonnement.

La désinscription ne signifie pas que l'observable est complet. Voyons la différence entre se désinscrire et terminer ensuite. 🛑✅

Se désinscrire vs. Terminé

Se désinscrire d'un observable empêche l'observable d'émettre plus de valeurs. Cependant, l'observable n'a peut-être pas terminé d'envoyer toutes les valeurs - il peut y avoir plus de valeurs dans sa séquence de données qui n'ont pas été envoyées.

Pour cette raison, unsubscribe() n'appelle pas complete( ) dans le cadre de la désinscription. La fonction observable appelle complete lorsqu'elle a effectivement fini d'émettre toutes les valeurs qu'elle devait émettre.

En revanche, lorsqu'un observable errors ou completesl'objet abonné appelle unsubscribe()libérant ainsi les ressources utilisées par l'abonnement et la fonction observable.

Depuis complete appelle unsubscribe derrière le scènes, nous n'avons pas besoin de nous désinscrire explicitement de l'abonnement pour libérer des ressources. Par exemple, notre observable voyelles$ émet des valeurs et se termine.

Cependant, toutes les observables ne sont pas complètes. Si nous ne nous désinscrivons pas de l'intervalle$ observable ci-dessous, il continuera à émettre des valeurs à chaque intervalle spécifié et provoquera une fuite de mémoire.

const intervalle$ = intervalle$ = intervalle(1000);

souscription = intervalle$.subscribe(console.log);

stopTimer( ) {  
  this.abonnement.unsubscribe();  
}

Veuillez vous référer à la démo StackBlitz pour le code complet.

Veuillez également vous référer à l'article RxJS: Don't Unsubscribe de Ben Lesh pour en savoir plus sur la gestion des abonnements de manière non impérative.

Résumé

Le secret pour comprendre les observables réside dans la connaissance de la manière dont un observable est créé. 🔐

Dans cette série d'articles en deux parties, nous nous sommes familiarisés avec la fonction observable. C'est la fonction que nous passons au constructeur observable pour créer une instance d'observable. La fonction observable contient le code pour produire des données et émettre des données et des notifications à l'abonné.

La fonction observable :

  • prend un objet abonné comme paramètre
  • produit des données au sein de la fonction ( observable à froid) ou se referme sur un producteur (observable à chaud)
  • émet une séquence de zéro à plusieurs valeurs soit de manière synchrone soit de manière asynchrone aux abonnés
  • avertit les abonnés si une erreur se produit ou s'il a terminé l'émission de toutes les données
  • renvoie le détachement function

Nous faisons savoir à une observable que nous voulons recevoir des données en appelant sa méthode subscribe() et en passant un objet observer. L'objet observer contient des rappels pour traiter les données et les notifications envoyées par l'observable.

L'abonnement à un observable exécute la fonction observable, transforme l'objet observateur en un objet abonné interne et renvoie un objet d'abonnement.[19659009]Nous pouvons nous désinscrire en exécutant la méthode unsubscribe() de l'objet d'abonnement. Le désabonnement efface les ressources utilisées par l'abonnement et exécute la fonction de suppression de l'observable. Il est important de se désabonner des observables pour éviter les fuites de mémoire — cependant, nous n'avons pas besoin de nous désabonner explicitement des observables qui sont complets.

Nous avons vu que les observables produisent des données — c'est pourquoi les observables sont parfois appelés source de données ou source. De plus, les observables peuvent émettre une séquence (ou un flux) de valeurs. Ainsi, les observables sont également appelés flux de données ou flux.

J'espère que cet article en deux parties a contribué à fournir une meilleure compréhension du type observable, ouvrant la voie à d'autres sujets relatifs aux observables et à la programmation réactive avec RxJS (operatorssubjects et schedulers).

Ressources

  1. Vous apprendrez RxJS à Ng-Europe 2016. C'est l'une de mes conférences préférées de tous les temps. Je suis sûr que vous allez adorer le regarder.
  2. Hot vs Cold Observables par Ben Lesh.
  3. Learning Observable By Building Observable par Ben Lesh.




Source link