Skip to content

Instantly share code, notes, and snippets.

@bloodyowl
Forked from wyeo/part2.md
Created October 29, 2017 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bloodyowl/ed9681b69f2f4511c81eef675a4e562e to your computer and use it in GitHub Desktop.
Save bloodyowl/ed9681b69f2f4511c81eef675a4e562e to your computer and use it in GitHub Desktop.
Observable

Bienvenue dans la deuxième partie du tutoriel sur les Observables.

Résumé de partie 1

Dans la première partie, nous avons vu que les Observables nous permettent de traiter des données synchrones et asynchrones. Aussi, nous avons vu la méthode subscribe() à laquelle nous appliquons notre Observer afin de consulter les données. Enfin dans le dernier exemple, une méthode unsubscribe() qui va nous permettre en tant que Observer d'avoir la possibilité de decider de ne plus écouter les données émises.

Vous l’aurez compris, les Observables sont surtout utilisés dans l’objectif de manipuler de la donnée asynchrone. Nous allons donc essayer de comprendre, comment est-ce que les données reçue peuvent être manipulées.

Prenons un cas concret pour illustrer notre problématique :

Imaginons que nous recevons toutes les lettres de l’alphabet en minuscule (a, b, c…) et que nous souhaitons leur appliquer une transformation : mettre en majuscule (A, B, C…)

// Implementation naïve

const observer = {
	next: val => console.log(val),
	error: err => console.log(err),
	complete: () => console.log('Complete!')
}

const alphabetObservable = {
	subscribe: observer => {
		const alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
		alphabet.forEach(letter => {
			const letterCapitalized = letter.toUpperCase()
			observer.next(letterCapitalized)
		})
		observer.complete()
	}
}

alphabetObservable.subscribe(observer) // log a b c d …

Plutôt que de simplement appeler la méthode subscribe(), l’observable pourrait nous donner la possibilité d’appliquer d’autres transformations comme par exemple :

  • Transformer les 21 premières lettres aux chiffres équivalents dans la table ASCII
  • Transformer les 5 dernières lettres en arabes
  • Et autres...

qui donnerait :

alphabetObservable
	.transformOnly21FirstLettersToAscii()
	.LowerCase()
	.transformOnly5LastLettersToArabicCharacter()
	.subscribe(observer)

Ces méthodes de transformations(aussi appelés “Operator”) peuvent être coupler dans l’ordre que l’on souhaite. Enfin pour accéder au résultat de notre transformation, nous allons appeler la méthode .subscribe() et lui appliquer notre observer. Appliquer ces transformations directement dans la méthode subscribe(), nous empêchent d’avoir de la flexibilité. Il nous faut donc une nouvelle façon d’implementer nos Observables pour mettre en place nos opérateurs (méthodes de transformations).

Les opérateurs : Méthodes de transformations

Un opérateur est une méthode de l’observable qui est appelée avant la méthode subscribe() pour effectuer une transformation sur la donnée.

Schema d’exploitation d’un Observable sans Opérateur :

Observable —> 1, 2, 3 —> subscribe // Affiche 1, 2, 3

Schema d’exploitation d’un Observable avec Opérateur :

Observable —> 1, 2, 3 —> add10 —> 10, 20, 30 —> subscribe // Affiche 10, 20, 30

L’opérateur add10() n’échappe pas à la règle : pour accéder aux données de l’Observable, il doit lui-même jouer le rôle de subscribe() ensuite permettre aux opérateurs qui le suivent de pouvoir accéder à ses données en renvoyant un observable à son tour. (Oui subscribe() est considéré comme un opérateur lui aussi)

Du code ! Du code :

const observer = {
	next: val => console.log(val),
	error: err => console.log(err),
	complete: () => console.log('Complete!')
}

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()
})
arrayObservable
	.map(x => x + 10)
	.subscribe(observer)

Nous avons maintenant une fonction createObservable(), qui est appelée à chaque fois qu’on a besoin de retourner un Observable avec l’ensemble des opérateurs.

Vous devez être en mesure de pouvoir appliquer toutes les transformations précedemment citées avec alphabetObservable : à vous de jouer ! :p

Présentation de la librairie RxJS

RxJS repose basiquement ce qu’on vient de voir précédemment avec beaucoup plus d’opérateurs et différents concepts avancés. Si vous souhaitez en savoir plus, je vous invite à vous rendre sur la documentation officielle.

  • Présenter le Marble diagram
  • Présenter 2-3 Opérateurs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment