Der beste Weg, um Observable aus rxjs zu importieren


79

In meiner Angular 2-App habe ich einen Dienst, der die ObservableKlasse aus der rxjsBibliothek verwendet.

import { Observable } from 'rxjs';

Im Moment benutze ich nur, Observabledamit ich die toPromise()Funktion nutzen kann.

Ich habe irgendwo in einer anderen StackOverflow-Frage gelesen, dass beim Importieren auf diese Weise und auch beim Importieren aus rxjs/Rxeine ganze Menge unnötiger Inhalte aus der rxjsBibliothek importiert werden , wodurch sich die Ladezeiten der Seiten und / oder die Codebasis erhöhen.

Meine Frage ist, wie Observableich am besten importieren kann, damit ich die toPromise()Funktion verwenden kann, ohne alles andere importieren zu müssen.


2
import {Observable} from 'rxjs/Observable';würde das Observable importieren, aber Sie müssen nicht alles importieren, wenn Sie Versprechen verwenden ... toPromisefunktioniert ohne es.
AJT82

Was müsste ich selbst importieren, um es nur zu verwenden toPromise? Ich benutze Observable, ich hätte das in der Frage klarstellen sollen. Es sind wirklich zwei getrennte Fragen.
Danoram

2
dann würde dies tun, wenn Sie Versprechen wollen Werfenimport 'rxjs/add/operator/toPromise'; Sie einen Blick auf angle.io/docs/ts/latest/tutorial/toh-pt6.html Das sollte Ihnen weiterhelfen :)
AJT82

Ich werde es untersuchen. Prost und danke, dass du dir die Zeit zum Teilen genommen hast!
Danoram

Kein Problem! Viel Spaß beim Codieren! :)
AJT82

Antworten:


137

Rxjs v 6. *

Es wurde mit einer neueren Version von rxjs vereinfacht.

1) Betreiber

import {map} from 'rxjs/operators';

2) Andere

import {Observable,of, from } from 'rxjs';

Anstatt zu verketten, müssen wir pfeifen. Zum Beispiel

Alte Syntax:

source.map().switchMap().subscribe()

Neue Syntax:

source.pipe(map(), switchMap()).subscribe()

Hinweis: Einige Operatoren haben eine Namensänderung aufgrund von Namenskollisionen mit reservierten JavaScript-Wörtern! Diese beinhalten:

do-> tap,

catch -> catchError

switch -> switchAll

finally -> finalize


Rxjs v 5. *

Ich schreibe diese Antwort teilweise, um mir selbst zu helfen, da ich jedes Mal, wenn ich einen Operator importieren muss, die Dokumente überprüfe. Lassen Sie mich wissen, ob etwas besser gemacht werden kann.

1) import { Rx } from 'rxjs/Rx';

Dadurch wird die gesamte Bibliothek importiert. Dann müssen Sie sich nicht um das Laden jedes Bedieners kümmern. Sie müssen jedoch Rx anhängen. Ich hoffe, dass das Baumschütteln optimiert wird und nur die benötigten Funktionen auswählt (muss überprüft werden). Wie in den Kommentaren erwähnt, kann das Baumschütteln nicht helfen. Das ist also nicht optimiert.

public cache = new Rx.BehaviorSubject('');

Oder Sie können einzelne Operatoren importieren .

Dadurch wird Ihre App so optimiert, dass nur die folgenden Dateien verwendet werden :

2) import { _______ } from 'rxjs/_________';

Diese Syntax wird normalerweise für Hauptobjekte wie sich Rxselbst oder Observableusw. verwendet.

Schlüsselwörter, die mit dieser Syntax importiert werden können

 Observable, Observer, BehaviorSubject, Subject, ReplaySubject

3) import 'rxjs/add/observable/__________';

Update für Angular 5

Mit Angular 5, das rxjs 5.5.2+ verwendet

import { empty } from 'rxjs/observable/empty';
import { concat} from 'rxjs/observable/concat';

Diese werden in der Regel direkt von Observable begleitet. Zum Beispiel

Observable.from()
Observable.of()

Andere solche Schlüsselwörter, die mit dieser Syntax importiert werden können:

concat, defer, empty, forkJoin, from, fromPromise, if, interval, merge, of, 
range, throw, timer, using, zip

4) import 'rxjs/add/operator/_________';

Update für Angular 5

Mit Angular 5, das rxjs 5.5.2+ verwendet

import { filter } from 'rxjs/operators/filter';
import { map } from 'rxjs/operators/map';

Diese kommen normalerweise in den Stream, nachdem das Observable erstellt wurde. Wie flatMapin diesem Code-Snippet:

Observable.of([1,2,3,4])
          .flatMap(arr => Observable.from(arr));

Andere solche Schlüsselwörter, die diese Syntax verwenden:

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 : flatMapist ein Alias ​​für, mergeMapalso müssen wir importieren, um es mergeMapzu verwenden flatMap.


Hinweis für /addImporte :

Wir müssen nur einmal im gesamten Projekt importieren. Es wird daher empfohlen, dies an einem einzigen Ort zu tun. Wenn sie in mehreren Dateien enthalten sind und eine davon gelöscht wird, schlägt der Build aus falschen Gründen fehl.


3
Das Baumschütteln kann hier nicht optimiert werden, da es auf den Symbolnamen der Export- und Importdefinitionen basiert und die RxJS-Operatormodule nichts exportieren, sondern stattdessen den globalen Status ändern. siehe
Mr. Smith

Ich denke, Sie müssen jeden Operator einzeln importieren, wie import {map} from 'rxjs / operator / map}; {filter} aus 'rxjs / operator / filter} importieren
Michael Burger

groupBy hat bei Angular 5+ nicht für mich gearbeitet, andere jedoch.
Joe

Gute Antwort. Ich wusste nicht , den Unterschied zwischen /add/operatorvs /operatorsImporten. Klappt wunderbar.
Stephen Chung

1
Cool, aber wo steht das in der Dokumentation? Ich finde die Dokumentation von Rxjs schwierig zu verwenden.
Robert Kusznier

22

Update für RxJS 6 (April 2018)

Es ist jetzt vollkommen in Ordnung, direkt von zu importieren rxjs. (Wie in Angular 6+ zu sehen ist). Der Import von rxjs/operatorsist ebenfalls in Ordnung und es ist tatsächlich nicht mehr möglich, Operatoren global zu importieren (einer der Hauptgründe für das Refactoring rxjs 6und den neuen Ansatzpipe ). Dank dieses Baumshakes kann nun auch verwendet werden.

Beispielcode aus rxjs repo:

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));

Abwärtskompatibilität für rxjs <6?

Das rxjs-Team hat auf npm ein Kompatibilitätspaket veröffentlicht, das so ziemlich install & play ist. Damit rxjs 5.xsollte Ihr gesamter Code ohne Probleme ausgeführt werden. Dies ist jetzt besonders nützlich, wenn die meisten Abhängigkeiten (dh Module für Angular) noch nicht aktualisiert wurden.


Ich hatte das Problem in Angular 6.0.0-rc.5. Und ich wusste nicht, dass es RxJS war, der die Änderung vorgenommen hatte. Ich habe auch den Filter aus dem Rohr entfernt.
M. Sundstrom

Es gibt viele Änderungen in RxJS6. Es wird dringend empfohlen, sich die Zeit zu nehmen, um diesen Artikel zu lesen: github.com/ReactiveX/rxjs/blob/master/MIGRATION.md und / oder auth0.com/blog/whats-new-in-rxjs-6, damit Sie sich auf RxJs7 vorbereiten können wirklich verschwinden. Wie @enn erwähnt, sollten Sie jetzt pipeMethoden verwenden, anstatt sie miteinander zu verketten
Simon_Weaver

In diesem Artikel werden die Vorteile von pipe gofore.com/de/lettable-operators-and-rxjs-versioning erläutert (es geht nicht speziell um Version 6, aber es hat mir geholfen zu verstehen, warum so viele drastische Änderungen in RxJS6 nicht gut erklärt werden ihr eigener Führer)
Simon_Weaver

3

Eine Sache, die ich auf die harte Tour gelernt habe, ist konsequent zu sein

Achten Sie auf das Mischen:

 import { BehaviorSubject } from "rxjs";

mit

 import { BehaviorSubject } from "rxjs/BehaviorSubject";

Dies funktioniert wahrscheinlich einwandfrei, BIS Sie versuchen, das Objekt an eine andere Klasse zu übergeben (wo Sie es anders gemacht haben), und dies kann dann fehlschlagen

 (myBehaviorSubject instanceof Observable)

Es schlägt fehl, weil die Prototypenkette anders und falsch ist.

Ich kann nicht so tun, als würde ich genau verstehen, was passiert, aber manchmal stoße ich darauf und muss zum längeren Format wechseln.


Wenn jemand dies bitte besser erklären kann, antworten Sie bitte :-)
Simon_Weaver

Visual Studio zum Beispiel importiert gerne "rxjs"Definitionen und führt sie zusammen, wo es anscheinend besser ist, sie separat im "langen" Format auszuführen.
Simon_Weaver
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.