0% ont trouvé ce document utile (0 vote)
193 vues41 pages

coursAngularRxJS PDF

Transféré par

ec-son
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
193 vues41 pages

coursAngularRxJS PDF

Transféré par

ec-son
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Angular : RxJS

Achref El Mouelhi

Docteur de l’université d’Aix-Marseille


Chercheur en programmation par contrainte (IA)
Ingénieur en génie logiciel

[Link]@[Link]

H & H: Research and Training 1 / 32


Plan
1 Introduction
2 Observable
3 Observer
4 Opérateurs
5 Combinaison d’opérateurs
6 Opérateurs d’agrégations
7 Fusion d’observables
8 Subject
9 Behavior Subject
10 Replay Subject
11 Async Subject

H & H: Research and Training 2 / 32


Introduction

Angular
Programmation réactive

paradigme de programmation orienté flux de données et


propagation des changements
inspiré du patron de conception observable
H I ©
Deux concepts importants :
U EL
O
f E LM
Observable : une fonction retournant un flux de valeurs à un

ch r e
observateur de manière synchrone ou asynchrone. Un observable
s’exécute s’il y a un observateur (observer) et un abonnement
© A
(avec la méthode subscribe())
Observer : un élément (objet) qui se souscrit (subscribe()) à un
observable pour recevoir les changements et exécuter une suite de
code

H & H: Research and Training 3 / 32


Introduction

Angular
Programmation réactive

paradigme de programmation orienté flux de données et


propagation des changements
inspiré du patron de conception observable
H I ©
Deux concepts importants :
U EL
O
f E LM
Observable : une fonction retournant un flux de valeurs à un

ch r e
observateur de manière synchrone ou asynchrone. Un observable
s’exécute s’il y a un observateur (observer) et un abonnement
© A
(avec la méthode subscribe())
Observer : un élément (objet) qui se souscrit (subscribe()) à un
observable pour recevoir les changements et exécuter une suite de
code

RxJS : Reactive extensions for JavaScript


H & H: Research and Training 3 / 32
Introduction

Angular

La méthode subscribe() prend trois paramètre


1
I ©
la première se déclenche à chaque fois que l’observable émet de
H
EL
nouvelles données (ces données sont reçues comme paramètre)
U
O
2

f E LM
la deuxième se déclenche si l’observable émet une erreur, et

ch r e
reçoit cette erreur comme paramètre
3
©A
la troisième se déclenche lorsque l’observable se termine, et ne
reçoit aucun paramètre.

H & H: Research and Training 4 / 32


Introduction

Angular

Pour commencer
H I ©
EL
OU
créez un composant observable
M
E L /app-observable> dans
ajoutez <app-observable><
f
chr e
[Link]
© A

H & H: Research and Training 5 / 32


Introduction

Le fichier [Link]
import { Component, OnInit } from ’@angular/core’;

@Component({
selector: ’app-observable’,
templateUrl: ’./[Link]’,
styleUrls: [’./[Link]’]
})
export class ObservableComponent implements OnInit {
H I ©
status = ’’;
UEL
tab: Array<number> = [];
O
constructor() { }
ngOnInit() { }
f E LM
}
ch r e
©A

H & H: Research and Training 6 / 32


Introduction

Le fichier [Link]
import { Component, OnInit } from ’@angular/core’;

@Component({
selector: ’app-observable’,
templateUrl: ’./[Link]’,
styleUrls: [’./[Link]’]
})
export class ObservableComponent implements OnInit {
H I ©
status = ’’;
UEL
tab: Array<number> = [];
O
constructor() { }
ngOnInit() { }
f E LM
}
ch r e
©A
Le fichier [Link]
<h1>éléments</h1>
<ul>
<li *ngFor="let elt of tab">
{{ elt }}
</li>
</ul>
<div>{{ status }}</div>
H & H: Research and Training 6 / 32
Observable

Angular
Pour créer un observable, on peut utiliser la méthode of() qui convertit un
ensemble de paramètres en observable
import { Component, OnInit } from ’@angular/core’;
import { Observable, of } from ’rxjs’;

@Component({
H I ©
selector: ’app-observable’,
U EL
templateUrl: ’./[Link]’,
O
})
f E LM
styleUrls: [’./[Link]’]

ch r e
export class ObservableComponent implements OnInit {

status = ’’; ©A
tab: Array<number> = [];
constructor() { }
ngOnInit(): void {
const observable: Observable<number> = of(1, 2, 3);
}
}

H & H: Research and Training 7 / 32


Observable

Angular
On peut utiliser from() pour construire un observable à partir d’un tableau
import { Component, OnInit } from ’@angular/core’;
import { Observable, from } from ’rxjs’;

@Component({
selector: ’app-observable’,
H I ©
templateUrl: ’./[Link]’,
U EL
styleUrls: [’./[Link]’]
O
})

f E LM
export class ObservableComponent implements OnInit {

ch r e
©A
status = ’’;
tab: Array<number> = [];
constructor() { }
ngOnInit() {
const tableau = [1, 2, 3];
const observable: Observable<number> = from(tableau);
}
}

H & H: Research and Training 8 / 32


Observable

Angular
On peut utiliser range() pour définir un interval de nombre entier

import { Component, OnInit } from ’@angular/core’;


import { Observable, range } from ’rxjs’;

@Component({
selector: ’app-observable’,
H I ©
templateUrl: ’./[Link]’,
U EL
styleUrls: [’./[Link]’]
O
})
f E LM
ch r e
export class ObservableComponent implements OnInit {

status = ’’;
©A
tab: Array<number> = [];
constructor() { }
ngOnInit() {
const observable: Observable<number> = range(1, 3);
}
}

H & H: Research and Training 9 / 32


Observer

Angular
Lorsqu’un observateur s’abonne à notre observable, il peut implémenter trois
méthodes pour spécifier ce qu’il faut faire

ngOnInit() {
const tableau = [1, 2, 3];
const observable: Observable<number> = from(tableau);
const observer: Observer<number> = {
H I ©
next: (value) => {
U EL
[Link](value);
O
},
f E LM
error: (error) => {
[Link] = error;
ch r e
},
complete: ©A
() => {
[Link] = ’fini’;
}
};

H & H: Research and Training 10 / 32


Observer

Angular
On peut aussi directement faire
ngOnInit() {
const tableau = [1, 2, 3];
const observable: Observable<number> = from(tableau);
[Link](
(value) => {
H I ©
},
[Link](value);
U EL
O
LM
(error) => {
[Link] = error;
r e f E
ch
},

©A
() => {
[Link] = ’fini’;
}
);
}

L’émission de valeurs s’effectue d’une manière synchrone et par conséquent on ne


voit pas la réception des éléments dans le navigateur.

H & H: Research and Training 11 / 32


Observer

Angular
Pour avoir une exécution asynchrone, on utilise la fonction interval(1000)
une infinité de valeurs incrémentielles commençant de 0 : une valeur par
seconde

ngOnInit() {

I ©
const observable: Observable<number> = interval(1000);
H
[Link](
(value) => {
UEL
O
LM
[Link](value);
},
(error) => {
r e f E
ch
©A
[Link] = error;
},
() => {
[Link] = ’fini’;
}
);
}

H & H: Research and Training 12 / 32


Observer

Pour avoir une exécution asynchrone, on utilise la fonction timer(3000,


1000) qui envoie une infinité de valeurs incrémentielles commençant de 0 : une
valeur par seconde la première valeur sera envoyée après 3 secondes

ngOnInit() {
const observable: Observable<number> = timer(3000, 1000);
[Link](
(value) => {
H I ©
EL
[Link](value);
},
O U
LM
(error) => {

},
[Link] = error;

r e f E
ch
©A
() => {
[Link] = ’fini’;
}
);
}

Les deux fonctions timer() et interval() ne se terminent jamais.

H & H: Research and Training 13 / 32


Observer

Pour éviter les problèmes de mémoire, il faut penser à se désabonner à la destruction du


composant

import { Component, OnInit, OnDestroy } from ’@angular/core’;


import { Observable, Subscription, timer } from ’rxjs’;
@Component({
selector: ’app-observable’,
templateUrl: ’./[Link]’,
styleUrls: [’./[Link]’]
})
H I ©
EL
export class ObservableComponent implements OnInit, OnDestroy {
tab: Array<number> = [];
O U
LM
status = ’’;
constructor() { }
subscription: Subscription;
r e f E
ch
ngOnInit() {

©A
const observable: Observable<number> = timer(3000, 1000);
[Link] = [Link](
(value) => { [Link](value); },
(error) => { [Link] = error; },
() => { [Link] = ’fini’; }
);
}
ngOnDestroy() { [Link](); }
}

H & H: Research and Training 14 / 32


Opérateurs

Angular
Pour indiquer le nombre d’élément à émettre, on utilise la méthode pipe() qui nous
permet de faire appel à l’opérateur take()

ngOnInit() {
const observable: Observable<number> = interval(1000).pipe(take(10));

[Link](
(value) => {
H I ©
[Link](value);
U EL
},
O
LM
(error) => {

},
[Link] = error;

r e f E
() => {
ch
);
} ©A
[Link] = ’fini’;

On peut importer les opérateurs ainsi : import { take } from ’rxjs/operators’;

H & H: Research and Training 15 / 32


Combinaison d’opérateurs

Angular
On peut combiner les opérateurs en appliquant une modification sur les 10
éléments reçus
ngOnInit() {
const observable: Observable<number> = interval(1000).pipe(
take(10),
map(elt => elt + 3)
H I ©
EL
);

O U
LM
[Link](
(value) => {
[Link](value);
r e f E
ch
©A
},
(error) => {
[Link] = error;
},
() => {
[Link] = ’fini’;
}
);
}
H & H: Research and Training 16 / 32
Combinaison d’opérateurs

Angular
On peut aussi filtrer les éléments pairs
ngOnInit() {
const observable: Observable<number> = interval(1000).pipe(
take(10),
map(elt => elt + 3),
filter(elt => elt % 2 === 0)
H I ©
EL
);

O U
LM
[Link](
(value) => {
[Link](value);
r e f E
ch
©A
},
(error) => {
[Link] = error;
},
() => {
[Link] = ’fini’;
}
);
}
H & H: Research and Training 17 / 32
Opérateurs d’agrégations

Angular
On peut aussi compter les éléments selon un critère
ngOnInit() {
const observable: Observable<number> = interval(1000).pipe(
take(10),
count(elt => elt % 2 === 0)
);
H I ©
[Link](
UEL
O
LM
(value) => {

},
[Link](value);
r e f E
ch
©A
(error) => {
[Link] = error;
},
() => {
[Link] = ’fini’;
}
);
}

H & H: Research and Training 18 / 32


Opérateurs d’agrégations

Angular
On peut sélectionner le maximum
ngOnInit() {
const observable: Observable<number> = interval(1000).pipe(
take(10),
max()
);
H I ©
[Link](
UEL
O
LM
(value) => {

},
[Link](value);
r e f E
ch
©A
(error) => {
[Link] = error;
},
() => {
[Link] = ’fini’;
}
);
}

H & H: Research and Training 19 / 32


Fusion d’observables

Angular
On peut fusionner plusieurs observables grâce à la fonction merge()
ngOnInit() {
const tableau = [1, 2, 3];
const observable1: Observable<number> = of(1, 2, 3);
const observable2: Observable<number> = of(4, 5, 6);
const merged = merge(
observable1,
H I ©
);
observable2

U EL
O
[Link](
f E LM
(value) => {

ch
[Link](value); r e
©A
},
(error) => {
[Link] = error;
},
() => {
[Link] = ’fini’;
}
);
}

H & H: Research and Training 20 / 32


Subject

Angular

Subject H I ©
U EL
O
Il a à la fois le rôle d’un observateur et d’un observable

f E LM
ch r e
Il autorise la souscription de plusieurs observateurs

©A

H & H: Research and Training 21 / 32


Subject

Angular
Dans ngOnInit(), commençons par déclarer un Subject
const subject = new Subject<number>();

H I ©
U EL
O
f E LM
ch r e
©A

H & H: Research and Training 22 / 32


Subject

Angular
Dans ngOnInit(), commençons par déclarer un Subject
const subject = new Subject<number>();

Plusieurs observateurs peuvent s’abonner à notre subject


[Link]({
H I ©
EL
next: (value) => [Link](‘A : ${value}‘)
});
O U
LM
[Link]({
next: (value) => [Link](‘B : ${value}‘)
});
r e f E
ch
©A

H & H: Research and Training 22 / 32


Subject

Angular
Dans ngOnInit(), commençons par déclarer un Subject
const subject = new Subject<number>();

Plusieurs observateurs peuvent s’abonner à notre subject


[Link]({
H I ©
EL
next: (value) => [Link](‘A : ${value}‘)
});
O U
LM
[Link]({
next: (value) => [Link](‘B : ${value}‘)
});
r e f E
ch
©A
Introduisons deux nouvelles valeurs à notre subject
[Link](1);
[Link](2);
// le résultat est
// A : 1
// B : 1
// A : 2
// B : 2
H & H: Research and Training 22 / 32
Subject

Un Subject est aussi un observateur, il peut donc s’abonner à un observable

ngOnInit() {
const subject = new Subject<number>();
[Link]({
next: (value) => [Link](‘A : ${value}‘)
});
[Link]({
next: (value) => [Link](‘B : ${value}‘)
});
H I ©
U EL
O
LM
[Link](subject);
}

r e f E
ch
©A

H & H: Research and Training 23 / 32


Subject

Un Subject est aussi un observateur, il peut donc s’abonner à un observable

ngOnInit() {
const subject = new Subject<number>();
[Link]({
next: (value) => [Link](‘A : ${value}‘)
});
[Link]({
next: (value) => [Link](‘B : ${value}‘)
});
H I ©
U EL
O
LM
[Link](subject);
}

r e f E
ch
Le résultat est ©A
// A : 1
// B : 1
// A : 2
// B : 2
// A : 3
// B : 3

H & H: Research and Training 23 / 32


Subject

Angular

Remarque

H I ©
EL
Un observable ne peut avoir qu’un seul observateur

O U
LM
Un observable peut utiliser l’opérateur multicast et un

r e f E
subject pour avoir plusieurs observateurs

A ch ainsi un ConnectableObservable et
L’observable devient
utilise la©
méthode connect pour propager les changements

H & H: Research and Training 24 / 32


Subject

Exemple
const observable: Observable<number> = from([1, 2, 3]);
const subject = new Subject<number>();

const multicasted = [Link](multicast(subject)) as


ConnectableObservable<number>;

[Link]({
next: (value) => [Link](‘A : ${value}‘)
H I ©
EL
});
[Link]({
O U
next: (value) => [Link](‘B : ${value}‘)
});
[Link]();
f E LM
ch r e
©A

H & H: Research and Training 25 / 32


Subject

Exemple
const observable: Observable<number> = from([1, 2, 3]);
const subject = new Subject<number>();

const multicasted = [Link](multicast(subject)) as


ConnectableObservable<number>;

[Link]({
next: (value) => [Link](‘A : ${value}‘)
H I ©
EL
});
[Link]({
O U
next: (value) => [Link](‘B : ${value}‘)
});
[Link]();
f E LM
ch r e
Le résultat est ©A
// A : 1
// B : 1
// A : 2
// B : 2
// A : 3
// B : 3

H & H: Research and Training 25 / 32


Subject

Angular
Pour se désabonner, on appelle la méthode unsubscribe() depuis la souscription
ngOnInit() {
const observable: Observable<number> = interval(1000).pipe(take(10)
);

const subject = new Subject<number>();

H I ©
EL
const multicasted = [Link](multicast(subject)) as
ConnectableObservable<number>;
O U
const a = [Link]({
f E LM
});
ch r e
next: (value) => [Link](‘A : ${value}‘)

©A
const b = [Link]({
next: (value) => [Link](‘B : ${value}‘)
});

[Link]();

setTimeout(() => [Link](), 3000);


setTimeout(() => [Link](), 5000);
}
H & H: Research and Training 26 / 32
Behavior Subject

Angular

Behavior Subject

H I ©
Une des variantes de Subject fonctionnant avec la notion de

EL
valeur actuelle

O U
LM
Il stocke la dernière valeur émise par ses observateurs

r e f E
Chaque fois qu’un nouvel observateur s’abonne, il reçoit
A ch
immédiatement la valeur actuelle
©
Le constructeur de la classe BehaviorSubject prend comme
paramètre la valeur initiale

H & H: Research and Training 27 / 32


Behavior Subject

Angular
Exemple
ngOnInit() {
const subject = new BehaviorSubject(0);
[Link]({
next: (value) => [Link](‘A : ${value}‘)
});
[Link](1);
H I ©
EL
[Link](2);
[Link]({
O U
LM
next: (value) => [Link](‘B : ${value}‘)
});
[Link](3);
r e f E
ch
}

©A

H & H: Research and Training 28 / 32


Behavior Subject

Angular
Exemple
ngOnInit() {
const subject = new BehaviorSubject(0);
[Link]({
next: (value) => [Link](‘A : ${value}‘)
});
[Link](1);
H I ©
EL
[Link](2);
[Link]({
O U
LM
next: (value) => [Link](‘B : ${value}‘)
});
[Link](3);
r e f E
ch
}

Le résultat est
©A
// A : 0
// A : 1
// A : 2
// B : 2
// A : 3
// B : 3
H & H: Research and Training 28 / 32
Replay Subject

Angular

ReplaySubject

H I ©
Une des variantes de Subject fonctionnant avec la notion de
EL
nombre de valeurs à conserver dans l’historique
U
M O
f E L dansabonn
Il conserve un nombre de valeurs l’historique afin qu’elles

c h r e
puissent être envoyées aux nouveaux és.

© A de la classe ReplaySubject prend comme


Le constructeur
paramètre le nombre de valeurs à conserver dans l’historique

H & H: Research and Training 29 / 32


Replay Subject

Exemple
ngOnInit() {
const subject = new ReplaySubject<number>(2);
[Link](0);
[Link]({
next: (value) => [Link](‘A : ${value}‘)
});
[Link](1);
[Link](2);
H I ©
EL
[Link]({
next: (value) => [Link](‘B : ${value}‘)
});
O U
}
[Link](3);

f E LM
ch r e
©A

H & H: Research and Training 30 / 32


Replay Subject

Exemple
ngOnInit() {
const subject = new ReplaySubject<number>(2);
[Link](0);
[Link]({
next: (value) => [Link](‘A : ${value}‘)
});
[Link](1);
[Link](2);
H I ©
EL
[Link]({
next: (value) => [Link](‘B : ${value}‘)
});
O U
}
[Link](3);

f E LM
ch r e
Le résultat est ©A
// A : 0
// A : 1
// A : 2
// B : 1
// B : 2
// A : 3
// B : 3
H & H: Research and Training 30 / 32
Async Subject

Angular

Async Subject
H I ©
Une des variantes de Subject
UEL
O
f E LM
Il envoie seulement la dernière valeur à ses observateurs et c’est

ch r e
lorsqu’il finit quel que soit l’ordre de leur abonnement

©A
Pour signaler sa fin, il appelle la méthode complete

H & H: Research and Training 31 / 32


Async Subject

Angular
Exemple
ngOnInit() {
const subject = new AsyncSubject();

[Link](0);
[Link]({
next: (value) => [Link](‘A : ${value}‘)
H I ©
EL
});
[Link](1);
O U
LM
[Link](2);
[Link]({

e f E
next: (value) => [Link](‘B : ${value}‘)
r
ch
});

©A
[Link](3);

[Link]();
}

H & H: Research and Training 32 / 32


Async Subject

Angular
Exemple
ngOnInit() {
const subject = new AsyncSubject();

[Link](0);
[Link]({
next: (value) => [Link](‘A : ${value}‘)
H I ©
EL
});
[Link](1);
O U
LM
[Link](2);
[Link]({

e f E
next: (value) => [Link](‘B : ${value}‘)
r
ch
});

©A
[Link](3);

[Link]();
}

Le résultat est
// A : 3
// B : 3

H & H: Research and Training 32 / 32

Vous aimerez peut-être aussi