我应该同时使用 `import 'rxjs/Rx'` 和 `import { Observable } from '@rxjs/Observable'` 吗?

6
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import { Observable } from '@rxjs/Observable';
import 'rxjs/Rx';
import 'rxjs/add/observable/throw';
@Component({});
export shellModule{}

这是我从某个地方复制下来的Angular应用程序代码片段(已删除导出模块中的定义)。我使用它来创建一个调用API的服务。
在这个特定文件中,为什么即使整个rxjs库已经被导入,Observable也要单独导入?如果一个特定的模块被完整地导入,为什么还要单独导入它的某个对象?我曾试图在论坛上提出这个问题,但没有得到答案。我想了解这是否有助于代码的优化。

不确定那行代码是否有效,包名是rxjs,所以它不应该找到类似@rxjs的东西。你应该只单独导入类型如Observable、Subject等,并根据需要导入各个操作符。 - Adrian Fâciu
此外,一个好的实践是将所有操作符导入组织到一个文件中,例如rxjs.imports.ts,并仅在那里使用它们。您只需要导入一次即可工作。 - Adrian Fâciu
2个回答

6

总体来说:

在Typescript中,模块的处理方式要求您要么使用import * as rx from 'rxjs/Rx'导入整个库,要么导入库中的特定导出模块以使用它,以便编译器加载类型。

仅导入您需要的特定模块可以设置您的应用程序使用Angular的AOT编译进行树摇。这不是由typescript编译器完成的,而是由一个名为rollup的工具完成的。因此,它可以帮助优化代码,但不会自动执行。

至于编译开销,导入整个库可能会稍微减慢编译器的速度...但除了大规模复杂的库外,这并不是一个非常强的观点。

我个人更喜欢导入特定的模块,因为这样调用代码会更清晰一些,因为我不需要使用全局名称来获取特定名称。例如:rx.ObservableObservable。一个很好的例子是lodash库(rxjs稍微复杂一些...)。
老实说,像这样导入整个库:import 'rxjs/Rx'对我来说没有意义。您应该只导入特定的导出模块。尝试将其删除,查看您获得了什么错误,然后改用* as rx语法。
至于rxjs - 当您想要导入特定运算符时,它有点棘手,比如此问题 - 因此获取特定运算符的方法是: import 'rxjs/add/observable/from' - 但这也需要对您的webpack进行一些调整,如所引用问题的答案中所述

4
让我们来看看 rxjs/Rx 模块导出了什么:
export { Subject, AnonymousSubject } from './Subject';
export { Observable } from './Observable';
export { Operator } from './Operator';
export { Observer } from './Observer';
export { Subscription } from './Subscription';
export { Subscriber } from './Subscriber';
export { AsyncSubject } from './AsyncSubject';
export { ReplaySubject } from './ReplaySubject';
export { BehaviorSubject } from './BehaviorSubject';
...

import './add/observable/bindCallback';
import './add/observable/bindNodeCallback';
import './add/observable/combineLatest';
...

因此,它导出了 RxJs 类,并从 add 文件夹中导入运算符。因此,您可以看到它加载了库中的所有内容。但它不会导出任何全局对象。因此,您需要像这样使用命名导出:

import * as Rx from 'rxjs/Rx'

要使用一个已导出的类:

Rx.Observable.of(12, 3);

这会模拟使用bundle加载库时的情况 - 一个全局的`Rx`对象:
<script src="rxjs/bundles/Rx.js">

如果你想在不使用全局对象Rx的情况下使用Observable,你需要单独导入它:

import { Observable } from '@rxjs/Observable';
Observable.of(1);

同时导入两个模块:

import { Observable } from '@rxjs/Observable';
import 'rxjs/Rx';

这不是一个好的实践方法,但如果你不想单独导入每个运算符,则可能会使用它。

另请参阅如何正确地从rxjs包中导入运算符


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接