Redux Observableを使用して別のアクションをディスパッチする前に、アクションのシーケンスを待つ必要がある使用例があります。私はいくつかの同様の質問を見てきましたが、私の特定のユースケースでこれらのアプローチをどのように使用できるかを理解することはできません。
本質的に私はそのようなことをしたいです:
action$
.ofType(PAGINATION_CLICKED) // This action occurred.
.ofType(FETCH_SUCCESS) // Then this action occurred after.
.map(() => analyticsAction()); // Dispatch analytics.
タイプFETCH_ERROR
の別のアクションが発生した場合などは、そのシーケンスをキャンセルしてやり直したいと思います。
すばらしい質問です。重要な点は、_action$
_がディスパッチされたときのすべてのアクションのホット/マルチキャストストリームであることです(サブジェクトです)。暑いので、何度も組み合わせることができ、すべて同じアクションの流れを聞いています。
_// uses switchMap so if another PAGINATION_CLICKED comes in
// before FETCH_SUCCESS we start over
action$
.ofType(PAGINATION_CLICKED)
.switchMap(() =>
action$.ofType(FETCH_SUCCESS)
.take(1) // <-------------------- very important!
.map(() => analyticsAction())
.takeUntil(action$.ofType(FETCH_ERROR))
);
_
したがって、_PAGINATION_CLICKED
_を受け取るたびに、単一の_FETCH_SUCCESS
_をリッスンする内部の監視可能チェーンのリッスンを開始します。 .take(1)
があることが重要です。そうしないと、複数の_FETCH_SUCCESS
_をリッスンし続けるため、奇妙なバグが発生する可能性があります。
最初に_FETCH_SUCCESS
_を受け取った場合、takeUntil
を使用して_FETCH_ERROR
_の待機をキャンセルします。
おまけとして、最初からやり直すだけでなく、エラーにも基づいていくつかの分析処理も実行したい場合は、race
を使用して2つのストリーム間で実際に競合することができます。最初に放出するものが勝つ。もう1つはサブスクライブされていません。
_action$
.ofType(PAGINATION_CLICKED)
.switchMap(() =>
Observable.race(
action$.ofType(FETCH_SUCCESS)
.take(1)
.map(() => analyticsAction()),
action$.ofType(FETCH_ERROR)
.take(1)
.map(() => someOtherAnalyticsAction())
)
);
_
以下は同じですが、静的演算子の代わりにrace
をインスタンス演算子として使用しています。これは、選択できるスタイル設定です。どちらも同じことをします。どちらかわかりやすい方を使用してください。
_action$
.ofType(PAGINATION_CLICKED)
.switchMap(() =>
action$.ofType(FETCH_SUCCESS)
.map(() => analyticsAction())
.race(
action$.ofType(FETCH_ERROR)
.map(() => someOtherAnalyticsAction())
)
.take(1)
);
_