以下の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)
]
}
フォークを使用する必要がある場合と使用しない場合
一般的に、fork
は、サガが非ブロッキングタスクを開始する必要がある場合に役立ちます。ここでの非ブロッキングとは、呼び出し元がタスクを開始し、完了するのを待たずに実行を継続することを意味します。
これが役立つさまざまな状況がありますが、主な2つの状況は次のとおりです。
あなたのトップレベルの物語は、最初のユースケースの例です。次のようなものがあります。
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
ディスパッチされるアクション。さらに、必要なときにキャンセルするために、参照を保持することができます。
完全を期すために、非ブロッキング呼び出しを開始する別の方法があります:spawn
。 fork
とspawn
の違いは、エラーとキャンセルが子から親へのバブルにバブルする方法です。