2017-10-12 61 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)) 
    ); 
    }); 
相關問題