La mejor manera de importar Observable desde rxjs

79

En mi aplicación angular 2 tengo un servicio que usa la Observableclase de la rxjsbiblioteca.

import { Observable } from 'rxjs';

Por el momento solo estoy usando Observablepara poder usar la toPromise()función.

Leí en otra pregunta de StackOverflow en alguna parte que importar de esta manera y también importar desde rxjs/Rximportará una gran cantidad de cosas innecesarias de la rxjsbiblioteca que aumentarán los tiempos de carga de la página y / o la base del código.

Mi pregunta es, ¿cuál es la mejor manera de importar Observablepara poder usar la toPromise()función sin tener que importar todo lo demás?

Danoram
fuente
2
import {Observable} from 'rxjs/Observable';importaría el Observable, pero no necesita importarlo todo si está usando promesas ... toPromisefunciona sin él.
AJT82
¿Qué necesitaría importar solo para usar solo toPromise? Estoy usando Observable, debería haberlo aclarado en la pregunta. en realidad son dos preguntas separadas.
Danoram
2
entonces esto sería suficiente, si quieres promesas import 'rxjs/add/operator/toPromise';Echa un vistazo a angular.io/docs/ts/latest/tutorial/toh-pt6.html Eso debería ayudarte :)
AJT82
Lo miraré. ¡Salud y gracias por tomarse el tiempo para compartir!
Danoram
¡No hay problema! ¡Feliz codificación! :)
AJT82

Respuestas:

138

Rxjs v 6. *

Se simplificó con la versión más nueva de rxjs.

1) Operadores

import {map} from 'rxjs/operators';

2) Otros

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

En lugar de encadenar, necesitamos canalizar. Por ejemplo

Sintaxis antigua:

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

Nueva sintaxis:

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

Nota: ¡ Algunos operadores tienen un cambio de nombre debido a colisiones de nombres con palabras reservadas de JavaScript! Éstas incluyen:

do-> tap,

catch -> catchError

switch -> switchAll

finally -> finalize


Rxjs v 5. *

Estoy escribiendo esta respuesta en parte para ayudarme a mí mismo, ya que sigo revisando los documentos cada vez que necesito importar un operador. Avísame si se puede hacer algo mejor.

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

Esto importa toda la biblioteca. Entonces no necesita preocuparse por cargar cada operador. Pero debe agregar Rx. Espero que la agitación de árboles optimice y elija solo las funciones necesarias (es necesario verificar) Como se mencionó en los comentarios, la agitación de árboles no puede ayudar. Entonces esta no es una forma optimizada.

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

O puede importar operadores individuales .

Esto optimizará su aplicación para usar solo esos archivos :

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

Esta sintaxis generalmente se usa para el objeto principal como él Rxmismo o Observableetc.,

Palabras clave que se pueden importar con esta sintaxis

 Observable, Observer, BehaviorSubject, Subject, ReplaySubject

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

Actualización para Angular 5

Con Angular 5, que usa rxjs 5.5.2+

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

Suelen ir acompañados de Observable directamente. Por ejemplo

Observable.from()
Observable.of()

Otras palabras clave que se pueden importar con esta sintaxis:

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

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

Actualización para Angular 5

Con Angular 5, que usa rxjs 5.5.2+

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

Por lo general, estos vienen en la secuencia después de que se crea el Observable. Como flatMapen este fragmento de código:

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

Otras palabras clave que utilizan esta sintaxis:

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 : flatMapes el alias de, por mergeMaplo que debemos importar mergeMappara usarlo flatMap.


Nota para las /addimportaciones :

Solo necesitamos importar una vez en todo el proyecto. Por eso se aconseja hacerlo en un solo lugar. Si se incluyen en varios archivos y uno de ellos se elimina, la compilación fallará por motivos incorrectos.

Vamshi
fuente
3
La agitación de árboles no se puede optimizar aquí, ya que se basa en los nombres de símbolo de las definiciones de exportación e importación y los módulos de operador RxJS no exportan nada, sino que cambian el estado global. ver
Sr. Smith
Creo que tienes que importar cualquier operador uno por uno como import {map} from 'rxjs / operator / map}; importar {filter} de 'rxjs / operator / filter}
Michael Burger
groupBy no funcionó para mí en Angular 5+, aunque otros sí.
Joe
Gran respuesta. No conocía la diferencia entre las importaciones /add/operatory /operatorslas Funciona de maravilla.
Stephen Chung
1
Genial, pero ¿dónde está eso en la documentación? Encuentro la documentación de Rxjs difícil de usar.
Robert Kusznier
22

Actualización para RxJS 6 (abril de 2018)

Ahora está perfectamente bien importar directamente desde rxjs. (Como se puede ver en Angular 6+). Importar desde rxjs/operatorstambién está bien y, en realidad, ya no es posible importar operadores a nivel mundial (una de las principales razones para la refactorización rxjs 6y el uso del nuevo enfoque pipe). Gracias a este treehaking ahora también se puede utilizar.

Código de muestra del repositorio de 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));

¿Compatibilidad con versiones anteriores para rxjs <6?

El equipo de rxjs lanzó un paquete de compatibilidad en npm que es prácticamente instalar y jugar. Con esto, todo su rxjs 5.xcódigo debería ejecutarse sin problemas. Esto es especialmente útil ahora cuando la mayoría de las dependencias (es decir, módulos para Angular) aún no están actualizadas.

Enn
fuente
Tuve el problema en Angular 6.0.0-rc.5. Y no sabía que era RxJS quien había hecho el cambio. También quité el filtro de la tubería.
M. Sundstrom
Hay muchos cambios en RxJS6. Recomiendo encarecidamente tomarse el tiempo para leer este github.com/ReactiveX/rxjs/blob/master/MIGRATION.md y / o auth0.com/blog/whats-new-in-rxjs-6 para que pueda prepararse para RxJs7 donde todo será realmente desaparecer. Como mencionó @enn, ahora debería usar en pipelugar de encadenar métodos juntos
Simon_Weaver
Este artículo es excelente para explicar los beneficios de pipe gofore.com/en/lettable-operators-and-rxjs-versioning (no se trata específicamente de la versión 6, pero me ayudó a comprender por qué tantos cambios drásticos en RxJS6 que no están bien explicados en su propia guía)
Simon_Weaver
3

Una cosa que he aprendido por las malas es ser consistente

Cuidado con la mezcla:

 import { BehaviorSubject } from "rxjs";

con

 import { BehaviorSubject } from "rxjs/BehaviorSubject";

Esto probablemente funcionará bien HASTA que intente pasar el objeto a otra clase (donde lo hizo al revés) y luego esto puede fallar

 (myBehaviorSubject instanceof Observable)

Falla porque la cadena del prototipo será diferente y será falsa.

No puedo fingir entender exactamente lo que está sucediendo, pero a veces me encuentro con esto y necesito cambiar al formato más largo.

Simon_Weaver
fuente
Si alguien puede explicar esto mejor, responda :-)
Simon_Weaver
Visual Studio, por ejemplo, importará "rxjs"y fusionará con gusto las definiciones donde parece que es mejor hacerlo por separado en el formato 'largo'.
Simon_Weaver