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.
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 next
error
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é.next
error
oucomplete
ne peut pas être appelé aprèsunsubscribe
.unsubscribe
est appelé surerror
oucomplete
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
next
error
etcomplete
. 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 :
- Elle accepte un objet observateur ou des fonctions de rappel en tant que paramètres.
- 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.
- Il exécute la fonction observable et passe l'abonné comme argument. à l'objet abonné.
- 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 :
- 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 next
error
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();
- 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) }
) ;
- 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
- 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.
- Hot vs Cold Observables par Ben Lesh.
- Learning Observable By Building Observable par Ben Lesh.
Source link