Redux Saga, кажется, блокирует выполнение, хотя сага запускается с `spawn` - PullRequest
0 голосов
/ 27 сентября 2019

Я использую следующую настройку в своем приложении React Native:

  1. Графический интерфейс использует connect из react-redux для запуска действия, скажем, типа MY_ACTION.Создатель действия - это функция, которая находится на опоре графического интерфейса (connect помещает ее туда).Итак, графический интерфейс вызывает this.props.sendMyAction() для отправки.
  2. В моей корневой саге у меня есть следующий диспетчер, который прослушивает MY_ACTION и вызывает фоновый процесс каждый раз, когда отправляется MY_ACTION:
    function* myActionWatcher() {
        yield takeEvery(MY_ACTION, function*() {
            yield spawn(backgroundSaga);
        });
    }

Кажется, это работает.Однако поток JS, похоже, возвращается к графическому интерфейсу только после завершения фоновой саги:

this.props.sendMyAction();
console.info('Sent action!');              // <---- only called after backgroundSaga finishes

Это кажется странным, учитывая, что spawn является именно тем механизмом разветвления, который разветвляет сагу васинхронный способ, то есть такой, что родительской саге не нужно ждать, пока она не закончится.

Что мне не хватает?

1 Ответ

1 голос
/ 27 сентября 2019

Что делает backgroundSaga?Если он начинается с синхронного блока кода, этот код должен будет завершиться, прежде чем управление сможет вернуться к родительской саге, или к редуксу, или к вашему компоненту.

Когда вы вызываете yield spawn(backgroundSaga),Вы создаете отдельную сагу и запускаете эту сагу .Сага будет работать до тех пор, пока не будет yields что-то асинхронное (обычно обещание).Тот факт, что дочерняя сага отделена, означает, что родительская сага может завершиться, даже если дочерняя сага не закончила, но родитель все еще должен ждать, пока ребенок не наберет yield.Только после того, как дочерняя сага уступает, управление возвращается обратно к родительской саге, а затем обратно к редуксу, а затем обратно к вашему компоненту реакции.

Например, предположим, что у меня есть следующее:

function* myActionWatcher() {
  yield takeEvery(MY_ACTION, function*() {
    console.log('PARENT: about to spawn');
    yield spawn(backgroundSaga);
    console.log('PARENT: after spawn');
  });
}


function* backgroundSaga() {
  console.log('CHILD: starting saga');
  const state = yield select();
  console.log('CHILD: after select');
  yield Promise.resolve();
  console.log('CHILD: after resolve');
}

Порядок журналов для этого будет:

  • 'РОДИТЕЛЬ: скоро появится'
  • 'РЕБЕНОК: начало саги'
  • 'РЕБЕНОК: послевыберите '
  • ' PARENT: после появления '
  • ' Отправлено! '<- из вашего компонента </li>
  • 'РЕБЕНОК: после разрешения'

Другими словами, дочерний процесс запускается немедленно, и все, что он делает синхронно (включая синхронные переходы к redux-saga)для информации) беги к завершению.Затем, когда он достигнет чего-то, асинхронный элемент управления вернется к родителю, а потом дочерний элемент возобновит работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...