web-dev-qa-db-ja.com

佐賀の実行がredux-sagaで完了するのを待つ方法は?

次のシナリオがあります。

export function* addCircle(circleApi, { payload }) {
    try {
        const response = yield apply(
            circleApi,
            circleApi.addCircle,
            [payload]
        );

        if (response.error_type) {
           yield put(addCircleFailedAction(response.error));
        } else {
            yield put(addCircleSucceededAction(response));
        }
    } catch (err) {
        console.error(err);
    }
}

export function* addTender(tenderApi, { payload }) {
    try {
       // NOTE: I want this to finish before continuing with rest of saga below.
       yield call(addCircleAction(payload.circlePayload));

       // Rest of saga removed for brevity.
    } catch (err) {
        console.error(err);
    }
}

つまり、基本的にaddCircleはAPI呼び出しを行っており、その成功に応じて適切なreduxアクションを呼び出します。次に、別のサガの中で、addCircleサガを担当するアクションを呼び出します。サガの残りの部分を続行する前に、そのアクションの実行を終了させます。呼び出しを使用しようとしましたが、基本的にはaddCircleサガの実行が完了するのを待ちません。それを待つ方法はありますか?私はコンポーネントの内側からaddCircleを呼び出し、それを待つ必要はありませんでしたが、この特定のインスタンスでは、佐賀の中で呼び出す必要があるため、実行が完了するのを待つ必要があります。アプリの状態を変更して、更新された状態をaddTenderサガの残りの部分で使用できるようにします。何か案は?

6
user9128740

コードスニペットのとおり、addCircleサガは、実行が完了する直前にaddCircleFailedActionまたはaddCircleSucceededActionアクションクリエーターを派遣します。ですから、addTenderサガでそれらのアクションを待つ必要があります。

基本的に、これはあなたがすべきことです。アクションの作成者名に基づいて、アクションタイプを推測しています。

yield call(addCircleAction(payload.circlePayload));
yield take([ADD_CIRCLE_FAILED_ACTION, ADD_CIRCLE_SUCCEEDED_ACTION]);

// Rest of the saga

ただし、エッジケースが1つあります。 catchサガのaddCircleブロックでアクションをディスパッチしていません。 addCircleExceptionActionブロック内でcatchというアクションをディスパッチして、次のような他のアクションと一緒にそれを待つことができます。

yield take([ADD_CIRCLE_FAILED_ACTION, ADD_CIRCLE_SUCCEEDED_ACTION, ADD_CIRCLE_EXCEPTION_ACTION]);
2
vahissan

AddRenderをトリガーする複数のアクションをディスパッチする場合、take(...)が実際にyield呼び出しの結果として発生したアクションを待機するという保証はありません。

export function* addCircle(circleApi, { payload }) {
  try {
      const response = yield apply(
          circleApi,
          circleApi.addCircle,
          [payload]
      );

      if (response.error_type) {
         yield put(addCircleFailedAction(response.error));
         return response;
      } else {
          yield put(addCircleSucceededAction(response));
          return response;
      }
  } catch (err) {
      console.error(err);
      return {err};
  }
}

export function* addTender(tenderApi, { payload }) {
  try {
     //because addCircle saga is returning something you can re use it
     // in other sagas.
     const result = yield call(addCircle,circleAPI?,payload.circlePayload);
     //check for result.error_type here
     // Rest of saga removed for brevity.
  } catch (err) {
      console.error(err);
  }
}

call は最初の引数としてアクションオブジェクトを取りません({context、fn}タイプのオブジェクトを取ります)ため、コードと受け入れられた回答はエラーになります。

アクションをディスパッチしてから、ディスパッチしたばかりのアクションの副作用であるかどうかに関係なく、別のアクションをリッスンするのは悪い設計です。これらのアクションは非同期でディスパッチします。アクションが完了するまでに同じ時間がかかることや、待機している副作用が開始時と同じ順序で提供されることは保証されていません。

0
HMR