Dans mon application angular 2, j'ai un service qui utilise la classe Observable
de la bibliothèque rxjs
.
import { Observable } from 'rxjs';
Pour le moment, je n'utilise que Observable
pour pouvoir utiliser la fonction toPromise()
.
J'ai lu quelque part dans une autre question de StackOverflow que l'importation de cette manière et également de rxjs/Rx
importera une quantité importante d'éléments inutiles de la bibliothèque rxjs
qui augmenteront les temps de chargement de la page et/ou la base de code. .
Ma question est la suivante: quel est le meilleur moyen d'importer Observable
pour pouvoir utiliser la fonction toPromise()
sans tout importer?
Cela a été simplifié avec la nouvelle version de rxjs.
import {map} from 'rxjs/operators';
import {Observable,of, from } from 'rxjs';
Au lieu de chaîner, nous devons canaliser. Par exemple
Ancienne syntaxe:
source.map().switchMap().subscribe()
Nouvelle syntaxe:
source.pipe(map(), switchMap()).subscribe()
Remarque: Certains opérateurs ont changé de nom en raison de collisions de noms avec des mots réservés par JavaScript! Ceux-ci inclus:
do
-> tap
,
catch
-> catchError
switch
-> switchAll
finally
-> finalize
J'écris cette réponse en partie pour m'aider moi-même, car je continue à vérifier les documents chaque fois que je dois importer un opérateur. Faites-moi savoir si quelque chose peut être fait mieux.
import { Rx } from 'rxjs/Rx'
;Cela importe la bibliothèque entière. Dans ce cas, vous n'avez pas à vous soucier de charger chaque opérateur. Mais vous devez ajouter Rx. J'espère que la gestion des arbres optimisera et ne sélectionnera que les fonctions nécessaires (vérification nécessaire) Comme mentionné dans les commentaires, la secousse des arbres ne peut pas aider. Donc, ce n'est pas optimisé.
public cache = new Rx.BehaviorSubject('');
Ou vous pouvez importer des opérateurs individuels.
Ceci optimisera votre application pour utiliser uniquement ces fichiers:
import { _______ } from 'rxjs/_________';
Cette syntaxe habituellement utilisée pour les objets principaux tels que Rx
lui-même ou Observable
etc.
Mots-clés pouvant être importés avec cette syntaxe
Observable, Observer, BehaviorSubject, Subject, ReplaySubject
import 'rxjs/add/observable/__________';
Mise à jour pour Angular 5
Avec Angular 5, qui utilise rxjs 5.5.2+
import { empty } from 'rxjs/observable/empty';
import { concat} from 'rxjs/observable/concat';
Ceux-ci sont généralement accompagnés directement par Observable. Par exemple
Observable.from()
Observable.of()
D'autres mots clés de ce type peuvent être importés à l'aide de cette syntaxe:
concat, defer, empty, forkJoin, from, fromPromise, if, interval, merge, of,
range, throw, timer, using, Zip
import 'rxjs/add/operator/_________';
Mise à jour pour Angular 5
Avec Angular 5, qui utilise rxjs 5.5.2+
import { filter } from 'rxjs/operators/filter';
import { map } from 'rxjs/operators/map';
Ceux-ci entrent généralement dans le flux après la création de l'observable. Comme flatMap
dans cet extrait de code:
Observable.of([1,2,3,4])
.flatMap(arr => Observable.from(arr));
D'autres mots-clés de ce type utilisent cette syntaxe:
audit, buffer, catch, combineAll, combineLatest, concat, count, debounce, delay,
distinct, do, every, expand, filter, finally, find , first, groupBy,
ignoreElements, isEmpty, last, let, map, max, merge, mergeMap, min, pluck,
publish, race, reduce, repeat, scan, skip, startWith, switch, switchMap, take,
takeUntil, throttle, timeout, toArray, toPromise, withLatestFrom, Zip
FlatMap: flatMap
est un alias pour mergeMap
il faut donc importer mergeMap
pour utiliser flatMap
.
note pour /add
importations:
Nous n'avons besoin d'importer qu'une fois dans l'ensemble du projet. Il est donc conseillé de le faire à un seul endroit. S'ils sont inclus dans plusieurs fichiers et que l'un d'eux est supprimé, la construction échouera pour de mauvaises raisons.
Mise à jour pour RxJS 6 (avril 2018)
Il est maintenant parfaitement correct d'importer directement de rxjs
. (Comme on peut le voir dans Angular 6+). Importer à partir de rxjs/operators
convient également et il n'est plus possible d'importer des opérateurs globalement (une des principales raisons du refactoring rxjs 6
et de la nouvelle approche utilisant pipe
). Merci à cette arborescence peut maintenant être utilisé aussi.
Exemple de code provenant du dépôt rxjs:
import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';
range(1, 200)
.pipe(filter(x => x % 2 === 1), map(x => x + x))
.subscribe(x => console.log(x));
Compatibilité avec les versions antérieures pour rxjs <6?
l’équipe de rxjs a publié un paquet de compatibilité sur npm qui est à peu près install & play. Avec cela, tout votre code rxjs 5.x
devrait fonctionner sans aucun problème. Ceci est particulièrement utile maintenant lorsque la plupart des dépendances (modules pour Angular) ne sont pas encore mises à jour.
Une chose que j'ai apprise à la dure est d'être cohérent
Attention au mixage:
import { BehaviorSubject } from "rxjs";
avec
import { BehaviorSubject } from "rxjs/BehaviorSubject";
Cela fonctionnera probablement très bien jusqu'à ce que vous essayiez de passer l'objet à une autre classe (où vous l'avez fait dans l'autre sens) et ensuite cela peut échouer.
(myBehaviorSubject instanceof Observable)
Cela échoue parce que la chaîne de prototypes sera différente et fausse.
Je ne peux pas prétendre comprendre exactement ce qui se passe, mais parfois je me heurte à cela et je dois passer au format plus long.