2017-10-12 86 views
0

我正在尝试创建一个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秒,

+0

你可以重新说明/详细说明你在问什么吗? – jayphelps

+0

我已经重新解决了这个问题,希望现在的问题更清楚 – sgaseretto

回答

0

这还没有测试过...

首先,需要单独从操作显示的消息导致该动作显示:

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)) 
    ); 
    }); 
相关问题