次のシナリオがあります。
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
サガの残りの部分で使用できるようにします。何か案は?
コードスニペットのとおり、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]);
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}タイプのオブジェクトを取ります)ため、コードと受け入れられた回答はエラーになります。
アクションをディスパッチしてから、ディスパッチしたばかりのアクションの副作用であるかどうかに関係なく、別のアクションをリッスンするのは悪い設計です。これらのアクションは非同期でディスパッチします。アクションが完了するまでに同じ時間がかかることや、待機している副作用が開始時と同じ順序で提供されることは保証されていません。