Skip to content

Instantly share code, notes, and snippets.

@wyeo
Last active April 9, 2018 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save wyeo/eb5442a27bb72386cb49a00730cad4cc to your computer and use it in GitHub Desktop.
Save wyeo/eb5442a27bb72386cb49a00730cad4cc to your computer and use it in GitHub Desktop.
Observable

La programmation reactive avec RxJS

La programmation reactive est un paradigme de programmation dont le concept repose sur l'émission de données depuis une ou plusieurs sources (producteurs) à destinations d'autres éléments appelés consommateurs. Elle repose sur le design pattern Observable - Observer implémenté par les observables, aisément manipulable via les operateurs.

Dans l'introduction aux observables, nous avons découvert cet objet permettant de souscrire à une source de donnée avec un Observer. Cette mécanique permet de réagir aux données émisent par l'Observable par le biais de Observer, et cela pendant toute la durée du flux.

Maintenant, voyons comment nous pouvons manipuler ce flux grâce aux opérateurs de transformation.

Les opérateurs

Un Observable peut se représenter comme un tableau dont les elements arrivent avec le temps. Vous connaissez probablement les méthodes Array.prototype.map, Array.prototype.filter. Nous appliquons le même principe avec les operateurs sur un observable :

KeyBoardObservable
  .map(x => String.fromCharCode(keyCode))
  .filter(x => /[a-z]/.text(x))
  .subscribe(observer)

Les opérateurs peuvent être coupler dans l’ordre que l’on souhaite. Mais pour accéder au résultat de notre transformation, nous devrons faire appel à l'operateur .subscribe() et lui appliquer un Observer.

Schema d’exploitation d’un observable sans opérateur :

ArrayObservable
	|--> 1, 2, 3 --> .subscribe(Observer) // Affiche 1, 2, 3

Schema d’exploitation d’un observable avec opérateurs :

ArrayObservable
	|—-> 1, 2, 3	—->	.map(x => x * 10)	--> 10, 20, 30
	|—-> 10, 20, 30	-->	.filter(x => x >= 20)	--> 20, 30
	|—-> 20, 30	-->	.subscribe(Observer)	--> // Affiche 20, 30

L'opérateur n’échappe pas à la règle : pour accéder aux données de l’observable, il doit dans un premier temps y souscrire. Ensuite devra renvoyer un nouvel observable(avec le resultat de sa transformation) à l'operateur qui suit.

Voyons maintenant un exemple simple d'implémetation des operateurs .map() et .subscribe() :

function createObservable (subscribe) {
	return {
		subscribe: subscribe
		map: function(transformFn) {
			const inputObservable = this
			const outputObservable = createObservable(function subscribe(outputObserver) {
				inputObservable.subscribe({
					next: function (x) {
						const y = transformFn(x)
						outputObserver.next(y)
					},
					error: function (err) {
						outputObserver.error(err)
					},
					complete: function() {
						outputObserver.complete()
					}
				})
			})
			return outputObservable
		}
	}
}

const ArrayObservable = createObservable(function subscribe(observer) {
	[1, 2, 3].forEach(val => observer.next(val))
	observer.complete()
})
const observer = {
	next: val => console.log(val),
	error: err => console.log(err),
	complete: () => console.log('Complete!')
}

ArrayObservable
	.map(x => x * 10)
	.subscribe(observer) // log: 10, 20, 30 et 'Complete!'

La bibliothèque RxJS

RxJS est une bibliothèque qui implémente la notion d'observables-observer et qui fournit tout un panel d'opérateurs(transformation, filtrage, combinaison et bien d'autres).

const Rx = require('rxjs')

const ArrayObservable$ = Rx.Observable.create((observer) => {
	[1, 2, 3].forEach(elem => {
		observer.next(elem)
	})
	observer.complete()
})

ArrayObservable$
	.map(x => x * 10)
	.filter(x => x >= 20)
	.subscribe({
		next: val => console.log(val),
		error: err => console.log(err),
		complete: () => console.log('Complete!')
	})

// log 20, 30

Pour pouvez vous aider des Marbles diagrams pour avoir une idée du fonctionnement de chaque operateur et des effets sur le flux de données.

Conclusion

Nous avons pu voir le fonctionnement du paradigme de la programmation reactive ainsi que des élements qui la composent. N'hésitez pas à vous exercer avec les operateurs, merger les observables entre eux pour bien assimuler leur fonctionnement.

Dans le prochain prochain chapitre, nous verrons les cas d'usages des Observables au sein d'une application React/Redux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment