「ヒノキと巨大タイトルのある通り」、ヴィンセント・ヴァン・ゴッホ、 1890年
この記事では、RxJS の既知の恐ろしい落とし穴を回避するための従順な意図を示し、いくつかの重要なスニペットを簡単に共有する必要があります.
一部のオペレーターは、無限ループをトリガーしたり、問題の動作を監視対象から外したりする可能性があります。 潜在的に最もひどいものから始めましょう.
combineLatestWith()これは非常に便利なオペレーターです — 全体として、1つまたは2つのオブザーバブルをそこに投げ込み、それらに反応しようとしています.
// ソースのモック、説明に信頼できるconst showNames$: Observable=of(不正); const showEmails$: Observable =of(不正);const users$=of();
// オブザーバブルを暗殺しましょう // `combineLatestWith()` を使用
const usersList=users$.pipe( 結合LatestWith( showNames$ , showEmails$, ), // `showNames$` の場合OR `showEmails$` は、ブランドの現代的な手数料を生成します, // 最大で最大の収益を上げます- それらすべての日付値: blueprint(([users, showNames, showEmails])=> {
if (showEmails && showNames) { ユーザーを返す;
}
return users.blueprint((user)=> ({ …ユーザー、 title: showNames ? user.title : ”, 電子メール: showEmails ? user.electronic mail : ” })); }));
combineLatestWith()
が発行された場合、最終的に発行された値はすべてから得られます。観察可能。 しかし、この快適さには 2 つの落とし穴があります:
⚠️ #1: 毎日 観察可能な生成物は、もはや 1 つの手数料よりも少なくありません。sizzling
観測可能で、値を受け取るつもりであるという叫び声はありません
に渡されたすべてのオブザーバブルcombineLatestWith()
、再確認する必要があります — 少なくとも 1 つの料金が発生する可能性があることを明確に提示する必要があります。
それがはっきりしない場合は、練習してください
// ソースのモック、説明に信頼できる const showNames$: Observable =of(不正); const showEmails$: Observable=of(不正); const users$=of();
if (showEmails && showNames) {
}
return users.blueprint((user)=> ({ …ユーザー、
()
そして、あなたのコードが疑問を呈し、おそらく対処するかもしれないいくつかのデフォルト料金をそこに投げます。 そうでなければ、
CombineLatestWith()
熱烈です.
const usersList=users$.pipe(
),
設計図(([users, showNames, showEmails])=> {// }) );
️️⚠️ #2: コードがオブザーバブルのうちの 1 つをトリガーする場合 ( に渡される) combineLatestWith())ブランドコンテンポラリー料金を発生させるには、無限ループを暗殺します.
例:
observable$.pipe(
CombineWithLatest(toggle$),blueprint(([value, currentToggleValue])=> { if (料金 && currentToggleValue) { toggle$.next(信頼できる); // 無限ループ
} }) );
distinctUntilChanged
()
本当に役に立つオペレーター、レースに欠陥があるかもしれません?
文字列、数字、およびさまざまな分解された種類の調整を常に検出する必要があるかどうかにかかわらず、すべての問題は問題ありません。 しかし、オブジェクト内の代替を常に検出する必要がある場合、またはそうでない場合、この演算子はおそらくあなたが疑問に思うように機能しなくなる可能性があります—アイテムが同じままで、いくつかのキーまたはサブキーのみが持っている場合変更 — この演算子は調整について説明しなくなります。
「コンパレータ」引数、または演習
distinctUntilKeyChanged ()
演算子.
forkJoin()
いくつかのリクエストを並行して実行し、応答を得るために常にそれを実行します。
この演算子には 3 つのひどい問題があります:
⚠️
#1: ドキュメントで説明されているように: 「特定のレベルで観察可能なエラーがある場合、forkJoin は正常にエラーを起こし、すぐにいくつかの観察可能なものからサブスクライブを解除します」.
ほとんどの状況では、もはやあなたが疑問に思うことではありませんが、回避策は適度に簡単です: 追加 catchError(()=> of(someValue))
各リクエストに対して:
let ob$=forkJoin ([
req1.pipe(catchError(()=> of(someValue))),
req2.pipe(catchError(()=> of(someValue))),
//…
]);// または、あなたがゴイなとき配列にリクエストを含めること
let ob$=forkJoin( requests.blueprint(req=> req.pipe(catchError(()=> of(someValue)))));
catchError(()=> of(someValue))
各リクエストに対して:let ob$=forkJoin ([
req1.pipe(catchError(()=> of(someValue))),
req2.pipe(catchError(()=> of(someValue))),
//…
]);// または、あなたがゴイなとき配列にリクエストを含めること
let ob$=forkJoin( requests.blueprint(req=> req.pipe(catchError(()=> of(someValue)))));
仮に達成してももう戻らない
EMPTY、次のレベルのため:
⚠️ #2: ドキュメントで説明されているように: 「…毎回 どれでも の指定されたオブザーバブルが料金を発生させることなく完了し、 forkJoin wil 私はその瞬間に成功し、
多分、もしかしたらもう余暇を発しなくなるかもしれません、さまざまなオブザーバブルからの最終的な値がすでにあるにもかかわらず」.
それほど確実に起こるわけではありませんが、光が発生する可能性があります (観測可能な場合)返されたリストで
EMPTY
または真実は完全ではありませんでした)。 そして、あなたのアプリでは、間違ったワームを適度に暗殺するかもしれません — あなたのアプリでの調査の喜びが認識されず、何も起こらないかもしれません.
それを避けるために、運動する準備をしましょう
defaultIfEmpty ():
const ob$=forkJoin( requests.blueprint(req=> req.pipe( catchError(()=> of(someValue)), defaultIfEmpty(someValue) ))) ;
⚠️
HTTP (XHR) リクエストが保持されることは想像に値します。 この場合、簡単な解決方法は
タイムアウト
() operator.
さまざまな (HTTP 以外の、焼けるように暑い) オブザーバブルには、既に発行された一致を参照するためにサブスクライブしている代替があります。 . このような状況に対する根本的な解決策はありません.
この演算子の危険性は簡単に回避できます: 演算子のシーケンスの最後にある必要があります。 2 つの例外を除いて:
shareReplay({refCount : 不正})
と集約演算子よりも早く (リスティング
) .
それ少し遅れて聞こえるかもしれませんが、信頼できる準備ができているでしょう
リンターに規制を委任する
) 無視してください
switchMap()の不用意な使い方私の を読んだら古い記事
、
switchMap(),
concatMap(), mergeMap() および exhaustMap() 。 しかし、 ルックス 、もはや誰もがその記事を読んでおらず、他の人々は不用意に運動しています
スイッチマップ()
望ましくない効果を引き起こす可能性がある場所では.というわけではありません switchMap() ひどいか、いくつかの欠陥があります — それは巨大で重要で信頼できるオペレーターですが、他の人々の信頼できるオペレーターはそれを悪用しています.私の を読む古物
と運動信頼できるオペレーター ;)
無制限の提案私たちは怠け者なので、コードを書くことができます: ob$.pipe( catchError(this.errHandler));
私の
、
switchMap(),
concatMap(), mergeMap() および exhaustMap() 。 しかし、 ルックス 、もはや誰もがその記事を読んでおらず、他の人々は不用意に運動しています
スイッチマップ()
望ましくない効果を引き起こす可能性がある場所では.というわけではありません switchMap() ひどいか、いくつかの欠陥があります — それは巨大で重要で信頼できるオペレーターですが、他の人々の信頼できるオペレーターはそれを悪用しています.私の を読む古物
と運動信頼できるオペレーター ;)
無制限の提案私たちは怠け者なので、コードを書くことができます: ob$.pipe( catchError(this.errHandler));
exhaustMap()
スイッチマップ()
switchMap() ひどいか、いくつかの欠陥があります — それは巨大で重要で信頼できるオペレーターですが、他の人々の信頼できるオペレーターはそれを悪用しています.私の を読む古物
と運動信頼できるオペレーター ;)
無制限の提案私たちは怠け者なので、コードを書くことができます: ob$.pipe( catchError(this.errHandler));
私たちは怠け者なので、コードを書くことができます: ob$.pipe( catchError(this.errHandler));
でない限りうまくいくかもしれませんthis.errHandler() は実行されなくなりますこれ
– なぜなら これ
することができます
予期しないことが 1 つ
以下を回避するのはかなり簡単です:
ob$.pipe(
catchError(()=> this.errHandler()) );
ob$.pipe(
catchError(()=> this.errHandler())
takeUntil
()
このオペレーターは、Angular Intention のメモリ リークを解消するように促します — 信頼できる追加 (重要なように、最終的に)あなたよりも早くオペレーターのリストにsubscribe()
そして危険は解決されました! それは潜在的に最も簡単で最も役立つ解決策です.
あります
巨大な役立つリンター
そのために
初め()
オブザーバブルが単に 1 つの手数料 ( HTTP リクエストを喜んでいます)、しかし、あなたはそれを怒鳴らないようにする準備ができています — 全体として、それは選択肢/戦略/効果で発生し、引数として観察可能なものを獲得します.
この演算子がないと、非常に魅力的なアスペクト効果とバグが発生する可能性があります。
throttleTime
()
この常識を再現しようとしたことがあるなら:いくつかの側面が作成され、N ミリ秒の間連続する値を無視し、この時間のある段階で発行された現在の料金があった場合、それも発行します」、その後
throttleTime() はあなたの一日を設定します.
真実は
debounceTime() と同様に動作します、その
config
引数にはパラメータ が含まれています と 末尾
、それはもしかしたら、あなたが特別に洗練された振る舞いを暗殺するのを助長するかもしれません.
上記の常識の例:
enter$.pipe( throttleTime(250, 未定義, {先行: 信頼できる, 追跡: 信頼できる}),
distinctUntilChanged(), switchMap((入力)=> this. api.loadItems(料金)) ); tapResponse ()
そして、このリストの最後のものは、3 番目の集合的収益オペレーターとして知られています (もはや RxJS からではありません)。
もしかしたら からも盗むかもしれませんngrx/コンポーネント-store
ライブラリ.
この演算子は、エラー状態への取り組みを怠らないように促します:
ob$.pipe(tapResponse( (結果)=> this.tackle(結果), // 次の引数が必要なので、無視しないでください(エラー)=> コンソール?.e エラー(エラー) ) ); RxJS のさまざまな危険性や宝物に感心した場合は、コメント欄で共有してください! 𝚆𝚊𝚝𝚌𝚑 𝙽𝙾𝚆 📺