Каков идиоматический способ запуска rootSaga?
Проект redux-saga существует уже довольно долгое время, но все же в этой библиотеке много запутанных вещей. И один из них: как начать свой rootSaga. Например, в учебном пособии beginner rootSaga запускается путем создания массива саг. Как этот
export default function* rootSaga() {
yield [
helloSaga(),
watchIncrementAsync()
]
}
Однако в с помощью сага-помощников раздел rootSaga состоит из двух разветвленных саг. Вот так:
export default function* rootSaga() {
yield fork(watchFetchUsers)
yield fork(watchCreateUser)
}
Такой же способ запуска rootSaga используется в примере async в регрессировании редукс-саги. Тем не менее, если вы проверите примеры реальных и торговых карт, вы увидите, что rootSagas там выдает массив разветвленных саг. Вот так:
export default function* root() {
yield [
fork(getAllProducts),
fork(watchGetProducts),
fork(watchCheckout)
]
}
Кроме того, если вы прочитаете некоторые обсуждения в проблемах с редукцией саги, вы увидите, что некоторые люди предлагают использовать spawn вместо fork для rootSaga для защиты вашего приложения от полного сбоя, если один из ваших разветвленных саг отменен из-за некоторых необработанное исключение.
Итак, какой способ является самым правильным способом запустить ваш rootSaga? И каковы различия между существующими?
Ответы
Ответ 1
Вы можете запустить несколько корней саги. Но у любой саги есть возможность начать новую сагу самостоятельно. Таким образом, можно запустить саму корневую сагу, которая создает другие саги.
Вам просто нужно знать, как ошибки распространяются на родительскую сагу. Если у вас есть одна корневая сага, а детская сага разбилась, по умолчанию ошибка будет распространяться на родителя, который завершится, что также убьет все остальные саги, начатые с этого родителя.
Вам решать это поведение. В соответствии с вашим приложением вы можете захотеть быстро работать (сделать все приложение непригодным для использования в случае возникновения такой проблемы) или сбой в безопасности, и попытаться заставить приложение продолжить работу, даже если некоторые части могут иметь проблемы.
Обычно я рекомендую вам запускать несколько корневых сагов, или ваша родительская сага использует spawn
вместо fork
, чтобы ваше приложение оставалось работоспособным, если произошел сбой. Обратите внимание, что также довольно легко забыть ловить ошибки в некоторых местах. Обычно вы не хотите, чтобы, например, все ваше приложение стало непригодным для использования, если один запрос API, который терпит неудачу
Изменить. Я бы рекомендовал взглянуть на https://github.com/yelouafi/redux-saga/issues/570
Ответ 2
Как создать rootSaga?
В соответствии с основным разработчиком redux-saga [1, 2], идиоматический способ создания rootSaga - использовать все Комбинатор эффектов. Также обратите внимание, что урожайность массивов из саг устарела.
Пример 1
Вы можете использовать что-то вроде this (+ all)
import { fork, all } from 'redux-saga/effects';
import firstSaga from './firstSaga';
import secondSaga from './secondSaga';
import thirdSaga from './thirdSaga';
export default function* rootSaga() {
yield all([
fork(firstSaga),
fork(secondSaga),
fork(thirdSaga),
]);
}
Пример 2
Взято отсюда
// foo.js
import { takeEvery } from 'redux-saga/effects';
export const fooSagas = [
takeEvery("FOO_A", fooASaga),
takeEvery("FOO_B", fooBSaga),
]
// bar.js
import { takeEvery } from 'redux-saga/effects';
export const barSagas = [
takeEvery("BAR_A", barASaga),
takeEvery("BAR_B", barBSaga),
];
// index.js
import { fooSagas } from './foo';
import { barSagas } from './bar';
export default function* rootSaga() {
yield all([
...fooSagas,
...barSagas
])
}
fork vs. spawn
fork и spawn оба будут возвращать объекты Task. Заданные задачи прикрепляются к родителям, тогда как нерешенные задачи отделяются от родителя.
Основываясь на выше, вы можете использовать fork для "критически важных задач", то есть "если эта задача не сработает, пожалуйста, сбой всего приложения" и икру для "некритических" задач, то есть "если эта задача не удалась, не распространяйте ошибку на родителя".