2016-12-22 4 views
1

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

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

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

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 для редукции 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)); 
    } 
} 

Затем передать эти функции саг к вашей функции генератора INVOKER, следующим образом:

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

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

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

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

+0

Спасибо за ваш ответ, он очень всесторонний и на самом деле отвечает на вопрос. Тем не менее, я забыл сказать (полностью моя вина), что у меня нет прямого доступа к саге (именно так, как я ее реализовал), и у меня есть только доступ к действиям. Я могу назвать действия, но не фактические саги. Я мог бы переработать его, чтобы получить доступ к саге напрямую, но для этого потребовалась бы большая переделка, если бы был способ использовать put или put.sync, это было бы лучше для моей текущей ситуации? – Anupheaus

+0

Ну, на самом деле, насколько вы кладете ключевое слово 'yield' перед' put' в генератор, так что это уже синхронно, в любом случае вам нужны другие действия для обработки успеха, чтобы вы могли слушать успех в вашем случае. –

Смежные вопросы