Цепочка асинхронных действий с использованием redux-sagas

У меня есть действие с именем initialiseApp, которое, очевидно, инициализирует приложение. Есть некоторые вещи, которые мне нужны от сервера, такие как информация о пользователе, стили и некоторые подробности о отображаемой странице (это одностраничное приложение). Я использую redux-sagas и не могу найти способ связать асинхронные действия так, чтобы они выполнялись В ПОРЯДКЕ, а не параллельно.

Мне нужно, чтобы информация о пользователе вызывалась ДО запроса какой-либо информации о стилях, потому что на стороне сервера выполняется запрос пользователя, который извлекает пользователя и настраивает некоторые вещи в сеансе. Поскольку стили запрашиваются параллельно в данный момент, он показывает ошибки, потому что пользователь еще не настроен на сервере.

Итак, я попытался использовать put.sync, но это не сработало, но вот мой код (кстати, я также использую TypeScript):

private *invokeAndWaitOn(action: IAction<any>) {
    const putSync = (put as any).sync; // The typings file for redux-sagas does not yet include put.sync
    yield putSync(action);      
}

private *invokeArrayOfActions(actions: IAction<any>[]) {
    for (let action of actions) {
        yield* this.invokeAndWaitOn(action);
    }
}

но, похоже, это не сработает, и я не могу найти примеров того, как правильно использовать эффект put.sync в redux-saga.

Кто-нибудь может увидеть, что я делаю неправильно, или есть лучший / правильный способ сделать это, пожалуйста?

Заранее спасибо.

1 ответ

Решение

Предположим, ради этого варианта использования у вас есть два действия fetchUser а также fetchStyle, Вы хотите запустить второе действие сразу после того, как первое действие выполнено успешно.

В этом случае вам нужно иметь два других действия для каждого, чтобы обработать Успех и Ошибка, чтобы ваши действия были следующими:

Для извлечения пользователя: fetchUser, fetchUserSuccess, а также fetchUserError

Для выбора стиля: fetchStyle, fetchStyleSuccess, а также fetchStyleError

затем заверните весь процесс извлечения, скажем, sagaFunction следующим образом:

private* fetchUserSaga() {
  try {
    yield put(fetchUser());
    let response = yield call(/* fetchUser API function */])
    yield put(fetchUserSuccess(response));
  } catch (err) {
    yield put(fetchUserFailure(err));
  }
}

Подсказка: ты должен использовать call эффект от redux-saga,

private* fetchStyleSaga() {
  try {
    yield put(fetchStyle());
    let response = yield call(/* fetchStyle API function */])
    yield put(fetchStyleSuccess(response));
  } catch (err) {
    yield put(fetchStyleFailure(err));
  }
}

Затем передайте эти функции sagas функции генератора invoker следующим образом:

/*
const sagas = [
  fetchUserSaga,
  fetchStyleSaga,
]; */

private* invokeArrayOfSagas(sagas: ISaga<any>[]) {
  for (let saga of sagas) {
    yield call(saga()); /* saga: fetchUserSaga || fetchStyleSaga */
  }
}

Это будет ждать, пока fetchUserSaga не будет завершено, затем запустите fetchStyleSaga.

Дополнительная информация: Если вы хотите сгруппировать некоторые действия и вызывать их параллельно, от них зависит другая группа действий, вы можете выдать их в массиве с одним yield ключевое слово, смотрите больше здесь.

Другие вопросы по тегам