web-dev-qa-db-ja.com

別の佐賀でアクション/佐賀を使用する

3つの非同期リクエストを実行し、3つのリクエストからの応答をフォローアップリクエストで使用する必要がある佐賀があります。説明するためのいくつかの擬似コードは次のとおりです。

function* useOtherActionsAndSagas(action) {
  try {
    const [response1, response2, response3] = yield [
      request1,
      request2, 
      request3
    ];

    const orderData = {
      ...response1,
      ...response2,
      ...response3,
    };

    const response4 = yield request4;

    yield put({ type: 'SUCCESS', data: response4 });
  } catch (e) {
    // handle error
  }

3つのリクエストrequest1request2、およびrequest3は、3つの別々のSagasに対応します。たとえば、request1の場合、次の行に沿って佐賀があります。

export function* request1(action) {
  try {
    const result = yield api.get(`/api/endpoint`);
    yield put({...action, type: ACTION1_SUCCESS, data: result});
  } catch (e) {
    yield put({...action, type: ACTION1_FAIL, errors: e});
  }
}

function* watchAction1() {
  yield* takeLatest(ACTION1, request1);
}

export default function* () {
  yield [fork(watchAction1)];
}

ここで、api.getAxios.get() のラッパーです。

その佐賀のこのウォッチャーは、対応するアクション/リデューサーに接続されています。

export const ACTION1 = "actions/ACTION1";
export const ACTION1_SUCCESS = "actions/ACTION1_SUCCESS";
export const ACTION1_FAIL = "actions/ACTION1_FAIL";

const initialState = {
  // Initial state
};

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case ACTION1:
      // return state
    case ACTION1_SUCCESS:
      // return state
    case ACTION1_FAIL:
      // return state
    };
    default:
      // return state;
  }
}

export function request1(data){return {type:ACTION1、data}; }

コードを保持するためにDRY親のサガにある既存のアクションとサガを利用したいと思っていました。これを行うには、次のことを試しました。

const [response1, response2, response3] = yield [
  put({type: ACTION1, data: data1}),
  put({type: ACTION2, data: data2}),
  put({type: ACTION3, data: data3})
];

これにより、各アクションとそれに対応するサガが正しく開始されます。ただし、要求からの応答は、割り当てられた変数では使用できません。つまり、response1response2、およびresponse3は、それらのアクション{type: "actions/ACTION1", data: data1}への参照であり、Promiseではありません。

この親佐賀でAxiosリクエストを複製することは可能だと思いますが、個々のリクエストに対して成功/失敗アクションを持つというボーナスを失います。

このような設定を使用することは可能ですか?もしそうなら、フォローアップリクエストで使用するために非同期リクエストからの応答をどのように取得できますか?

そうでない場合、これを達成するための正しい方法は何ですか?

更新

次のように、親サガ内の他のSagasのワーカーを使用できます。

import request1 from request1Saga;

const [response1, response2, response3] = yield [
  call(request1, data1),
  call(request2, data2),
  call(request3, data3),
];

ここで、request1request2、およびrequest3は、他のSagasのワーカー関数です。これにより、使用されているSagasのACTION1_SUCCESSおよびACTION1_FAILアクションのメリットが得られます。

8
Brett DeWoody

必要なのは、allコンビネータとcallエフェクトを組み合わせるだけです( サガの作成 および タスクの並列実行 のドキュメント):

const [response1, response2, response3] = yield all([
  call(request1),
  call(request2), 
  call(request3)
]);

これにより、sagasが並行して実行され、それぞれから結果が返されます。 Promise.allとして機能します。

上記のサガ(request1からrequest3)は、サガの最後にいくつかのデータを返す必要があります。

export function* request1(action) {
  try {
    const result = yield call(url => api.get(url), `/api/endpoint`);
    yield put({...action, type: ACTION1_SUCCESS, data: result});
    // This will be assigned to result1
    return result
  } catch (e) {
    yield put({...action, type: ACTION1_FAIL, errors: e});
  }
}

:takeEveryはすでに「フォーク」されているため、フォークする必要はありません。

// Example of root saga:
export default function* () {
  yield takeLatest(ACTION1, request1);
  yield takeLatest(ACTION2, request2);
  // ...
}
3
Tomáš Ehrlich