从rxjs导入Observable的最佳方法


79

在我的angular 2应用程序中,我有一个使用库中Observable类的服务rxjs

import { Observable } from 'rxjs';

目前,我正在使用Observable以便可以使用该toPromise()功能。

我在另一个地方的另一个StackOverflow问题中读到,以这种方式导入并从中rxjs/Rx导入也会从rxjs库中导入大量不必要的内容,这将增加页面加载时间和/或代码库。

我的问题是,什么是最好的导入方式,Observable以便我可以使用该toPromise()功能而不必导入其他所有内容?


2
import {Observable} from 'rxjs/Observable';会导入Observable,但是如果您正在使用promises,则不需要全部导入toPromise它。
AJT82

我需要自己导入什么才能使用just toPromise?我正在使用Observable,我应该在问题中对此进行澄清。这实际上是两个独立的问题。
Danoram

2
那么就可以了,如果您要承诺import 'rxjs/add/operator/toPromise';的话,请看一下angular.io/docs/ts/latest/tutorial/toh-pt6.html这应该对您有帮助:)
AJT82,2017年

我会调查一下。干杯,感谢您抽出宝贵的时间分享!
Danoram '17

没问题!祝您编码愉快!:)
AJT82'2

Answers:


137

Rxjs v 6. *

较新版本的rxjs对此进行了简化。

1)运营商

import {map} from 'rxjs/operators';

2)其他

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

代替链接,我们需要管道。例如

旧语法:

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

新语法:

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

注意:由于与JavaScript保留字的名称冲突,某些运算符会更改名称!这些包括:

do-> tap

catch -> catchError

switch -> switchAll

finally -> finalize


Rxjs v 5. *

我写这个答案部分是为了帮助自己,因为我每次需要导入运算符时都会不断检查文档。让我知道是否可以做一些更好的方法。

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

这将导入整个库。然后,您不必担心加载每个运算符。但是您需要附加Rx。我希望摇树将优化并仅选择所需的功能(需要验证),如注释中所述,摇树无济于事。所以这不是优化的方式。

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

或者,您可以导入单个运算符。

这将优化您的应用程序以仅使用那些文件

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

这种语法通常用于主要对象(例如Rx自身或类似对象)Observable

可以使用此语法导入的关键字

 Observable, Observer, BehaviorSubject, Subject, ReplaySubject

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

更新Angular 5

Angular 5使用rxjs 5.5.2+

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

这些通常直接与Observable一起使用。例如

Observable.from()
Observable.of()

可以使用以下语法导入的其他此类关键字:

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

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

更新Angular 5

Angular 5使用rxjs 5.5.2+

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

这些通常在创建Observable之后进入流中。像下面flatMap的代码片段一样:

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

其他使用以下语法的此类关键字:

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

FlatMapflatMap是的别名,mergeMap因此我们需要导入mergeMap才能使用flatMap


/add进口注意事项

在整个项目中,我们只需要导入一次。因此,建议在一个地方进行。如果它们包含在多个文件中,并且其中一个被删除,则由于错误的原因,构建将失败。


3
摇树在此处无法优化,因为它依赖于导出和导入定义的符号名称,并且RxJS操作符模块不导出任何内容,而是更改全局状态。看到
史密斯先生

我认为您必须像从'rxjs / operators / map} import {map}一样导入任何运算符;从'rxjs / operators / filter}导入{过滤器}
Michael Burger

groupBy在Angular 5+上对我不起作用,其他人则对。

好答案。我不知道/add/operator/operators进口之间的区别。奇迹般有效。
斯蒂芬·钟

1
很酷,但是文档在哪里?我发现Rxjs文档很难使用。
罗伯特·库兹尼尔

22

RxJS 6更新(2018年4月)

现在可以直接从导入了rxjs。(可以在Angular 6+中看到)。从导入rxjs/operators也很好,实际上不再可能在全球范围内导入运算符(重构的主要原因之一rxjs 6和使用的新方法pipe)。由于有了这种树形交换,现在也可以使用。

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

是否向后兼容rxjs <6?

rxjs团队在npm上发布了一个兼容性软件包,该软件包几乎可以安装并播放。有了这些,您的所有rxjs 5.x代码都应该没有问题地运行。现在,当大多数依赖项(即Angular的模块)尚未更新时,这尤其有用。


我在Angular 6.0.0-rc.5中遇到了问题。我不知道是由RxJS进行了更改。我还从管道上拆下了过滤器。
M. Sundstrom '18 -4-26

RxJS6中有很多更改。强烈建议您花时间阅读此github.com/ReactiveX/rxjs/blob/master/MIGRATION.md和/或auth0.com/blog/whats-new-in-rxjs-6,以便您可以为RxJs7做准备真的消失了。正如@enn所提到的,您现在应该一起使用pipe而不是链接方法
Simon_Weaver

这篇文章很好地解释了pipe gofore.com/en/lettable-operators-and-rxjs-versioning的好处(它不是专门针对版本6的,但可以帮助我理解为什么RxJS6中有如此大的变化,而在本章中并没有很好地解释他们自己的指南)
Simon_Weaver

3

我学到的困难的一件事是保持一致

注意混合:

 import { BehaviorSubject } from "rxjs";

 import { BehaviorSubject } from "rxjs/BehaviorSubject";

除非您尝试将对象传递给另一个类(以其他方式在其中进行操作),否则这可能会很好地工作,然后这可能会失败

 (myBehaviorSubject instanceof Observable)

之所以失败,是因为原型链将有所不同,而且将是错误的。

我无法假装确切了解正在发生的事情,但是有时我碰到了这种情况,需要更改为更长的格式。


如果有人可以更好地解释这一点,请回复:-)
Simon_Weaver

例如,Visual Studio会很高兴地从"rxjs"定义中导入并将它们合并在一起,在这种情况下,最好还是以“长”格式分别进行定义。
Simon_Weaver
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.