[英]How to make two requests inside one epic [redux-observable]?
我對 rxjs 和 redux-observable 很陌生。 我正在嘗試在一個史詩中發出兩個 ajax 請求,如下所示:
import { mergeMap, filter, map, catchError } from 'rxjs/operators'; import { of } from 'rxjs'; import { ofType } from 'redux-observable'; import { push } from 'connected-react-router'; export const doSomething = (action$: any, state$: any) => action$.pipe( ofType('SOMETHING_HAPPEND'), filter((action: any) => action.payload.status === 'SOME_ACTION'), mergeMap(() => ajax.getJSON('/api/somewhere').pipe( map(() => push('some_route')), catchError((error: ResponseError) => of(statusChangeError(error))) ) ), filter(() => { const { startTime, endTime } = getFormData(state$.value); return startTime && endTime; }), mergeMap(() => ajax({ url: './api/another', method: 'POST', body: getFormData(state$.value), }).pipe( map(() => push('another_route')), catchError((error: ResponseError) => of(statusChangeError(error))) ) ) );
第一個請求必須始終運行。 第二個請求是有條件的,我有filter
。 我不確定這是否是做這些事情的正確方法。 它似乎正在工作,除了這部分
map(() => push('some_route')),
在第一個mergeMap
沒有被調用。 第二個mergeMap
的相同部分運行良好。
我究竟做錯了什么?
對/api/somewhere
的請求引發錯誤。 您的catchError
導致從mergeMap
ped observable 發出statusChangeError(error)
的結果。 由於后續的過濾器運算符會忽略發出的值,因此它不關心該值是否為錯誤。 因此,如果您的過濾器謂詞通過,則第二個mergeMap
會收到一個事件。
我建議不要像現在這樣使用filter
和map
,尤其是filter
。 您的映射函數會忽略發出的值,並且似乎每次都返回undefined
。 如果要在發出值時觸發副作用,請使用tap
運算符。
同樣,您的過濾器謂詞會忽略發出的值,而是檢查一些外部狀態。 像這樣的結構會使你的程序更難推理。 您可以使 observables 越“純”(例如發出不可變值),您的代碼就越可測試且越合理。
我會發布該答案,它可能不是問題的確切答案。 但這是標題中問題的答案,我想分享我的解決方案。 您可以使用fromPromise
並使用這樣的普通承諾:
export const fetchUserEpic = action$ =>
action$.pipe(
ofType(FETCH_USER),
mergeMap(() =>
fromPromise(
fetchUser()
.then(userResponse =>
fetchMoreInfo()
.then(moreInfoResponse => [userResponse, moreInfoResponse]
),
),
).pipe(
map(([userResponse, moreInfoResponse]) =>
fetchUserFullfilledAction(userResponse.data, moreInfoResponse.data),
),
),
),
);
其中fetchUser
和fetchMoreInfo
返回普通承諾(例如來自axios()
)。 如果你不關心順序,你可以使用Promise.all()
。 您可以使用async
await
重寫 fetch 函數
使用該解決方案,您可以放松對不同錯誤處理的控制,但如果您不需要該解決方案,則該解決方案可能是最簡單和最簡單的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.