私のAngular 2アプリでは、Observable
ライブラリのrxjs
クラスを使用するサービスを利用しています。
import { Observable } from 'rxjs';
現時点ではObservable
を使用しているだけなので、toPromise()
関数を使用できます。
私は別のStackOverflowの質問で、この方法でインポートしてrxjs/Rx
からインポートすると、rxjs
ライブラリから不要なものが大量にインポートされ、ページのロード時間やコードベースが増加することがあることを読みました。
私の質問は、Observable
をインポートして他のものをすべてインポートしなくてもtoPromise()
関数を使用できるようにする最善の方法は何ですか?
それはrxjsの新しいバージョンで単純化されました。
import {map} from 'rxjs/operators';
import {Observable,of, from } from 'rxjs';
連鎖するのではなく、パイプする必要があります。例えば
旧構文:
source.map().switchMap().subscribe()
新しい構文:
source.pipe(map(), switchMap()).subscribe()
注:一部の演算子では、JavaScriptの予約語と名前が衝突して名前が変更されています。これらが含まれます:
do
- > tap
、
catch
- > catchError
switch
- > switchAll
finally
- > finalize
私はオペレータをインポートする必要があるたびにドキュメントをチェックし続けるので、私は部分的にこの答えを書いています。何かもっと良い方法でできるかどうか教えてください。
import { Rx } from 'rxjs/Rx'
;これはライブラリ全体をインポートします。そうすれば、各演算子をロードすることについて心配する必要はありません。しかし、あなたはRxを追加する必要があります。 私は、ツリーの揺れが必要な機能だけを最適化して選ぶことを願っています コメントで述べたように、ツリーシェイクは役に立ちません。だからこれは最適化された方法ではありません。
public cache = new Rx.BehaviorSubject('');
あるいは個別の演算子をインポートすることもできます。
これにより、これらのファイルのみを使用するようにアプリが最適化されます:
import { _______ } from 'rxjs/_________';
この構文は通常、Rx
自体やObservable
などのメインオブジェクトに使用されます。
この構文でインポートできるキーワード
Observable, Observer, BehaviorSubject, Subject, ReplaySubject
import 'rxjs/add/observable/__________';
Angular 5の更新
Rxjs 5.5.2以降を使用するAngular 5
import { empty } from 'rxjs/observable/empty';
import { concat} from 'rxjs/observable/concat';
これらは通常オブザーバブルに直接付属しています。例えば
Observable.from()
Observable.of()
この構文を使用してインポートできるその他のキーワード
concat, defer, empty, forkJoin, from, fromPromise, if, interval, merge, of,
range, throw, timer, using, Zip
import 'rxjs/add/operator/_________';
Angular 5の更新
Rxjs 5.5.2以降を使用するAngular 5
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
FlatMap:flatMap
はmergeMap
の別名なので、mergeMap
を使用するにはflatMap
をインポートする必要があります。
/add
インポートに関するメモ:
プロジェクト全体で一度だけインポートする必要があります。それで、それは単一の場所でそれをすることを勧めました。それらが複数のファイルに含まれていて、そのうちの1つが削除されていると、ビルドは間違った理由で失敗します。
RxJS 6用の更新(2018年4月)
rxjs
から直接インポートしてもまったく問題ありません。 (Angular 6+に見られるように)。 rxjs/operators
からのインポートも問題ありません。実際には、演算子をグローバルにインポートすることはもはや不可能です(rxjs 6
をリファクタリングする主な理由の1つと、pipe
を使用する新しいアプローチ)。このツリーシェイクのおかげで今も同様に使用することができます。
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));
rxjs <6に対する下位互換性?
rxjsチームがnpmで compatibility package をリリースしました。これはほとんどインストール&プレイです。これであなたのすべてのrxjs 5.x
コードは問題なく動くはずです。これは、依存関係のほとんど(つまりAngularのモジュール)がまだ更新されていない場合に特に便利です。
私が苦労して学んだことの1つは、一貫性があることです。
混合に気をつけろ:
import { BehaviorSubject } from "rxjs";
と
import { BehaviorSubject } from "rxjs/BehaviorSubject";
これはおそらくあなたが他のクラスにオブジェクトを渡そうとするまで(あなたが他の方法でそれをやったところ)うまくいくでしょう、そしてこれは失敗する可能性があります。
(myBehaviorSubject instanceof Observable)
プロトタイプチェーンが異なるため、失敗します。
何が起こっているのか正確に理解するふりをすることはできませんが、時々私はこれに遭遇してより長いフォーマットに変更する必要があります。