Подтвердить что ты не робот

Каков идиоматический способ запуска 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? И каковы различия между существующими?

4b9b3361

Ответ 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. Заданные задачи прикрепляются к родителям, тогда как нерешенные задачи отделяются от родителя.

  • Обработка ошибок в forks [ссылка]:

    Ошибки от дочерних задач автоматически переходят к родителям. Если любая разветвленная задача вызывает непонятную ошибку, тогда родительская задача будет abort с дочерней ошибкой и всем родительским деревом исполнения (т.е. forked tasks + основная задача, представленная родительским органом, если он все еще работает) будет отменен.

  • Обработка ошибок в нерешенных задачах [ссылка]:

    Родитель не будет ждать завершения отдельных операций перед возвратом, и все события, которые могут повлиять на родителя или отдельную задачу, полностью независимы (ошибка, аннулирование).

Основываясь на выше, вы можете использовать fork для "критически важных задач", то есть "если эта задача не сработает, пожалуйста, сбой всего приложения" и икру для "некритических" задач, то есть "если эта задача не удалась, не распространяйте ошибку на родителя".