したがって、マップが移動したときにapiリクエストを更新するユースケースがありますが、それは小さなマップの移動でいくつかの迅速な発砲リクエストを生成する可能性があり、最後のものを除くすべての機内リクエストをキャンセルしたいと思います。 debounceを使用して、遅延した後にのみリクエストを送信できます。ただし、古いリクエストがまだ処理中の場合はキャンセルしたい。
const fetchNearbyStoresEpic = action$ =>
action$.ofType(FETCH_NEARBY_STORES)
.debounceTime(500)
.switchMap(action =>
db.collection('stores')
.where('location', '<=', action.payload.max).
.where('location', '>=', action.payload.min)
.map(response => fetchNearbyStoresFulfilled(response))
.takeUntil(action$.ofType(FETCH_STORES_CANCELLED))
);
takeUntil
を使用できることがわかりましたが、キャンセルアクションを明示的に起動する必要があります。私はドキュメントでswitchMapが最新のものを取り、他のすべてをキャンセルすることを知っています-私のAPI呼び出しにキャンセルインターフェースを実装する必要がありますか?この場合、firestoreへのfirebaseクエリになります。
GitHubの問題の コメント から:
それらには時間の次元があるため、オブザーバブルには複数の平坦化戦略があります。
mergeMap
(エイリアスとしてflatMap
を使用)を使用すると、受信したオブザーバブルが同時にサブスクライブされ、それらの発行された値が出力ストリームにフラット化されます。concatMap
を使用すると、受信したオブザーバブルがキューに入れられ、それぞれが完了するたびにサブスクライブされます。 (concatMap
はmergeMap
であり、同時実行性は1です。)switchMap
を使用すると、オブザーバブルが受信されると、それがサブスクライブされ、以前に受信されたオブザーバブルへのサブスクリプションがサブスクライブ解除されます。exhaustMap
を使用すると、以前に受信したオブザーバブルへのサブスクリプションがなく、そのオブザーバブルがまだ完了していない場合を除いて、オブザーバブルを受信するとサブスクライブされます。この場合、受信したオブザーバブルは無視されます。
したがって、マークが彼の回答で述べたように、switchMap
が後続のアクションを受信すると、不完全な要求のサブスクライブが解除されます。
ただし、デバウンスされたアクションがswitchMap
に到達するまで、リクエストはキャンセルされません。デバウンス期間を待つのではなく、別の移動の直後に保留中の要求をキャンセルしたい場合は、FETCH_NEARBY_STORES
アクションでtakeUntil
を使用できます。
const fetchNearbyStoresEpic = action$ =>
action$.ofType(FETCH_NEARBY_STORES)
.debounceTime(500)
.switchMap(action =>
db.collection('stores')
.where('location', '<=', action.payload.max).
.where('location', '>=', action.payload.min)
.map(response => fetchNearbyStoresFulfilled(response))
.takeUntil(action$.ofType(FETCH_NEARBY_STORES))
);
これは、別の移動の要求からの即時の退会に影響を与えるはずです。 (頭上では、action$
のredux-observable
の動作を思い出せません。takeUntil
に渡されたオブザーバブルにskip(1)
を追加する必要がある可能性があります。お試しください参照してください。)
そして、マークが述べたように、これはサブスクリプション解除時にリクエストをキャンセルする基本的な実装に基づいています。
switchMap
は、新しいエミッションが送信されると、以前のオブザーバブルを破棄します。基盤となるHTTPライブラリに応じて、キャンセルがサポートされている場合(Observable対応)、これで十分です。
質問では実装の詳細が提供されていないため、fetchNearbyStoresFulfilled
を調べて、Observable対応のhttpクライアントを使用しているかどうかを確認する必要があります。内部でpromiseを使用している場合、キャンセルのサポートは提供されません。