一种方法是(使用假名),接收初始动作API_GET_REQUEST
当你立即开始监听单INITIALIZE_FULFILLED
,这标志着该初始化(或其他)具有completed--我们会实际启动一下。收到后,我们mergeMap
(或switchMap
,以您的用例为准)进入我们的调用中,以完成其他ajax请求并执行常规业务。最后,启动我们正在等待的实际初始化的诀窍是在整个链的末尾添加一个startWith()
- 它将发出并派发其他史诗正在等待的动作。
const initializeEpic = action$ =>
action$.ofType('INITIALIZE')
.switchMap(() =>
someHowInitialize()
.map(() => ({
type: 'INITIALIZE_FULFILLED'
}))
);
const getRequestEpic = (action$, store) =>
action$.ofType('API_GET_REQUEST')
.switchMap(() =>
action$.ofType('INITIALIZE_FULFILLED')
.take(1) // don't listen forever! IMPORTANT!
.switchMap(() => {
let url = store.getState().apiDomain + action.payload;
return ajax(get(url))
.map(xhr => ({
type: types.API_RESPONSE,
payload: xhr.response
}))
.catch(error => Observable.of({
type: 'API_ERROR',
payload: error
}));
})
.startWith({
type: 'INITIALIZE'
})
);
你没有提到一切是如何工作的,所以这只是你需要修改你的用例的伪代码。
所有这一切说,如果你永远不要调用初始化除了在这个位置,你也只需要直接包括代码在单史诗本身,或者只是使抽象成为一个辅助函数。将它们保持为独立的史诗通常意味着您的UI代码可以独立触发它们中的任何一个 - 但为了测试目的,它们可能仍然很好。只有你可以打这个电话。
const getRequestEpic = (action$, store) =>
action$.ofType('API_GET_REQUEST')
.switchMap(() =>
someHowInitialize()
.mergeMap(() => {
let url = store.getState().apiDomain + action.payload;
return ajax(get(url))
.map(xhr => ({
type: types.API_RESPONSE,
payload: xhr.response
}))
.catch(error => Observable.of({
type: 'API_ERROR',
payload: error
}));
})
.startWith({ // dunno if you still need this in your reducers?
type: 'INITIALIZE_FULFILLED'
})
);