Какая разница между двумя подходами ниже?
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, а когда нет?
В общем случае fork
полезно, когда саге нужно запустить неблокирующую задачу. Неблокирование здесь означает: вызывающий абонент запускает задачу и продолжает выполнение, не дожидаясь завершения.
Существует множество ситуаций, когда это может быть полезно, но два основных:
Сага о высшем уровне может быть примером первого варианта использования. Вероятно, у вас есть что-то вроде:
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
сам представляет собой разветвленную задачу, поэтому в большинстве случаев это будет бесполезно избыточным.
Примером второго варианта использования может быть что-то вроде:
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
отличаются тем, как ошибки и отмены пузырьки от ребенка к родительской саге.