如何在使用redux-observables时正确地排列动作的时间
问题描述:
我正在尝试创建一个Epic来排列要分派的动作,在这种情况下,这些动作是要使用快捷栏显示的消息,例如,三个错误几乎同时发生,我想用SnackBar显示三条错误消息,Epic应该调度一个动作来显示第一个消息3秒钟,然后显示第二个消息3秒钟,然后第三个消息显示3秒钟。如何在使用redux-observables时正确地排列动作的时间
另外,如果其中一个小吃店被关闭,应该显示“队列”中的第二个,等等。我现在正在做的是调度在Epics中显示消息以捕获错误的操作,然后我创建Epics通过CLOSE_SNACKBAR操作在3秒的延迟后分派关闭快餐栏的操作。我应该使用哪些方法来实现这个目标?
基本史诗我实现了这个样子的,基本上是从小吃吧,打开改变状态,并显示错误消息从另一个史诗布控,映入错误的一个动作,然后另一史诗调度3秒后关闭快餐栏的动作,但我还没有想出如何执行这种排队操作,以便每个消息可以显示3秒钟,现在如果错误发生在第一个之后,第二条消息将显示而不等待前一条消息后的3秒钟。 这里是我史诗的一些基本的例子(忽略去请求部分):
const getUserEpic = (action$, store) => (
action$.ofType(actionTypes.DATA_REQUESTED)
.switchMap(action => {
const { orderData, queryData, pagerData } = store.getState().usuario.list;
const params = constructParams(queryData, pagerData, orderData);
return Observable.defer(() => axios.get(`users`, { params }))
.retry(NETWORK.RETRIES).mergeMap(response => {
Observable.of(actions.dataRequestSucceeded(response.data.rows))
}).catch(error => Observable.concat(
Observable.of(actions.dataRequestFailed(error)),
Observable.of({
type:'DISPLAY_DATA_REQUEST_FAILED_MESSAGE',
open:true,
message:'Failed to get Users Data'
})
));
})
)
const getRoleEpic = (action$, store) => (
action$.ofType(actionTypes.DATA_REQUESTED)
.switchMap(action => {
const { orderData, queryData, pagerData } = store.getState().usuario.list;
const params = constructParams(queryData, pagerData, orderData);
return Observable.defer(() => axios.get(`role`, { params }))
.retry(NETWORK.RETRIES).mergeMap(response => {
Observable.of(actions.dataRequestSucceeded(response.data.rows))
}).catch(error => Observable.concat(
Observable.of(actions.dataRequestFailed(error)),
Observable.of({
type:'DISPLAY_DATA_REQUEST_FAILED_MESSAGE',
open:true,
message:'Failed to get Roles Data'
})
));
})
)
这两部史诗基本上做攻方,他们正在做一个GET请求到后端,但如果他们失败了,他们发送打开快捷栏的操作并显示错误消息,并且这两个错误消息都不相同。
而这一次,目前在3秒后关闭小吃吧史诗:
const displayDataRequestFailedEpic = (action$, store) => (
action$.ofType(actionTypes.DISPLAY_DATA_REQUEST_FAILED)
.debounceTime(3e3)
.switchMap(action => {
return Observable.of({
type:'CLOSE_SNACKBAR',
open:false,
message:''
})
})
)
想象一下我做的这两个请求实在是快,他们都失败。我想表明所发生的一切错误,陆续为每3秒,
答
这还没有测试过...
首先,需要单独从操作显示的消息导致该动作显示:
const getUserEpic = (action$, store) => (
action$.ofType(actionTypes.DATA_REQUESTED)
.switchMap(action => {
const { orderData, queryData, pagerData } = store.getState().usuario.list;
const params = constructParams(queryData, pagerData, orderData);
return Observable.defer(() => axios.get(`users`, { params }))
.retry(NETWORK.RETRIES).mergeMap(response => {
return Observable.of(actions.dataRequestSucceeded(response.data.rows))
}).catch(error => Observable.of(actions.dateRequestFailed(error))
// }).catch(error => Observable.concat(
// Observable.of(actions.dataRequestFailed(error)),
//
// this will be handled elsewhere
//
// Observable.of({
// type:'DISPLAY_DATA_REQUEST_FAILED_MESSAGE',
// open:true,
// message:'Failed to get Users Data'
// })
));
})
)
下,需要定义一些用于创建从任何动作触发消息的DISPLAY_MESSAGE
操作方法。动作中应包含一个唯一的ID,用于跟踪哪些消息需要关闭。
最后,使用concatMap()
来创建和销毁消息。
const displayEpic = action$ => action$
.ofType(actionTypes.DATA_REQUEST_FAILED)
.concatMap(action => {
const messageAction = actions.displayMessage(action);
const { id } = messageAction;
return Rx.Observable.merge(
Rx.Observable.of(messageAction),
Rx.Observable.of(actions.closeMessage(id))
.delay(3000)
.takeUntil(action$
.ofType(actionTypes.CLOSE_MESSAGE)
.filter(a => a.id === id))
);
});
你可以重新说明/详细说明你在问什么吗? – jayphelps
我已经重新解决了这个问题,希望现在的问题更清楚 – sgaseretto