所以我有一个用例,我在移动地图时更新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查询。
答案 0 :(得分:7)
来自GitHub问题中的comment I made:
因为它们有时间维度,所以对于可观察对象有多种展平策略:
- 使用
mergeMap
(其中flatMap
作为别名),收到的observables会同时订阅,并且它们的发布值会被平展到输出流中。- 使用
concatMap
,收到的可观察对象排队,并在每个完成时一个接一个地订阅。 (concatMap
是mergeMap
,并发为一。)- 使用
switchMap
,当收到一个观察者时,它已订阅,并且对以前收到的观察者的任何订阅都已取消订阅。- 使用
exhaustMap
,当收到一个observable时,它会订阅,除非订阅了之前收到的observable并且该observable尚未完成 - 在这种情况下,接收的observable将被忽略。< / LI>
所以,就像马克在答案中所说,当switchMap
收到后续行动时,它会取消订阅任何不完整的请求。
但是,在去抖操作进入switchMap
之前,该请求不会被取消。如果您想在另一次移动时立即取消任何待处理的请求 - 而不是等待去抖持续时间 - 您可以takeUntil
使用FETCH_NEARBY_STORES
操作:
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
的行为。您可能需要将skip(1)
附加到传递给{的观察者身上{1}}。试一试,看看。)
而且,正如马克所说,这取决于取消订阅时取消请求的基础实施。
答案 1 :(得分:4)
switchMap
将放弃其先前的可观测量。根据您的基础HTTP库以及它是否支持取消(Observable aware),这应该足够了。
由于您的问题中未提供任何实施细节,因此您必须查看fetchNearbyStoresFulfilled
以查看它是否使用了Observable感知的http客户端。如果它在内部使用promises,则不提供取消支持。