web-dev-qa-db-ja.com

redux-sagaはいつフォークを使用しますか?

以下の2つのアプローチの違いは何ですか?

export function* watchLoginUser() {
  yield takeEvery(USER_LOGIN, loginUser)
}
export function* watchLogoutUser() {
  yield takeEvery(USER_LOGOUT, logoutUser)
}
export function* watchGetParties() {
  yield takeEvery(PARTIES_GET, getParties)
}
export default function* root() {
  yield [
    fork(watchLoginUser),
    fork(watchLogoutUser),
    fork(watchGetParties)
  ]
}
export default function* root() {
  yield [
    takeEvery(USER_LOGIN, loginUser),
    takeEvery(USER_LOGOUT, logoutUser),
    takeEvery(PARTIES_GET, getParties)
  ]
}

フォークを使用する必要がある場合と使用しない場合

28

一般的に、forkは、サガが非ブロッキングタスクを開始する必要がある場合に役立ちます。ここでの非ブロッキングとは、呼び出し元がタスクを開始し、完了するのを待たずに実行を継続することを意味します。

これが役立つさまざまな状況がありますが、主な2つの状況は次のとおりです。

  • 論理ドメインによるsagasのグループ化
  • タスクをキャンセル/参加できるように、タスクへの参照を保持する

あなたのトップレベルの物語は、最初のユースケースの例です。次のようなものがあります。

yield fork(authSaga);
yield fork(myDomainSpecificSaga);
// you could use here something like yield [];
// but it wouldn't make any difference here

authSagaには次のようなものが含まれる可能性があります。

yield takeEvery(USER_REQUESTED_LOGIN, authenticateUser);
yield takeEvery(USER_REQUESTED_LOGOUT, logoutUser);

この例は、forkを使用してtakeEvery呼び出しを生成するサガを呼び出して、提案したものと同等であることがわかります。しかし、実際には、コード編成の目的でのみこれを行う必要があります。 takeEveryはそれ自体分岐タスクであるため、ほとんどの場合、これは無駄に冗長になります。

2番目のユースケースの例は次のようになります。

yield take(USER_WAS_AUTHENTICATED);
const task = yield fork(monitorUserProfileUpdates);
yield take(USER_SIGNED_OUT);
yield cancel(task);

この例では、呼び出し元のサガが再開している間にmonitorUserProfileUpdatesが実行され、USER_SIGNED_OUTディスパッチされるアクション。さらに、必要なときにキャンセルするために、参照を保持することができます。

完全を期すために、非ブロッキング呼び出しを開始する別の方法があります:spawnforkspawnの違いは、エラーとキャンセルが子から親へのバブルにバブルする方法です。

59
VonD