2017-02-23 11 views
0

redux-observableで私は別の叙事詩が完了するまでAPI要求を行う前に待つ必要があります。 combineLatestを使用しても機能しない場合、APP_INITIALIZEDが終了しても何も起こりません。私もLestestFromで試しましたが、どちらもうまくいきません。別の叙事詩が値を出すまで叙事詩を遅らせる方法

const apiGetRequestEpic = (action$, store) => { 
    return Observable.combineLatest(
    action$.ofType('APP_INITIALIZED'), 
    action$.ofType('API_GET_REQUEST') 
     .mergeMap((action) => { 
     let url = store.getState().apiDomain + action.payload; 
     return ajax(get(url)) 
      .map(xhr => { 
      return {type: types.API_RESPONSE, payload: xhr.response}; 
      }) 
      .catch(error => { 
      return Observable.of({ type: 'API_ERROR', payload: error }); 
      }); 
     }) 
); 
}; 

combineLatest definition

答えて

2

一つの手法(疑似名を使用して)で初期アクションAPI_GET_REQUESTを受信したとき、あなたはすぐに初期化(または何でも)ことを知らせるれ、単一INITIALIZE_FULFILLEDのリッスンを開始していcompleted--私たちは実際にそれを少しでもキックオフします。受け取った場合は、他のajaxリクエストを行い、通常のビジネスを行うために、mergeMap(またはご使用の場合はswitchMap)を呼び出します。最後に、私たちが待っている実際の初期化を開始するトリックは、チェーン全体の最後にstartWith()を追加することです。これにより、もう1つの叙事詩が待っているアクションが送出され、ディスパッチされます。

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' 
     }) 
    ); 

あなたはすべての仕組みが言及していないので、これはあなたのユースケースのために修正する必要がある疑似コードです。


あなたはこの場所以外でその初期化を呼び出していない場合、あなたはまた、1つだけの叙事詩自体に直接そのコードを含めるか、単にそれを抽象化するヘルパー関数を作ることができ、言ったすべてのこと。別々の叙事詩としてそれらを保持することは、通常、あなたの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' 
     }) 
    ); 
関連する問題