Асинхронная функция промежуточного программного обеспечения Redux

У меня есть промежуточное ПО Redux, которое взаимодействует с остальным API. Недавно я начал переписывать некоторые функции выборки, используя async/await.

Чтобы это имело для меня наибольший смысл, мне нужно, чтобы сама функция промежуточного программного обеспечения была асинхронной, чтобы я мог использовать блоки «ожидание» и try/catch для тех других асинхронных функций, которые я создал, а не использовать . тогда .поймай.

Пока у меня это:

const apiMiddleware = ({
  dispatch,
  getState
}) => next => async action => {
  switch (action.type) {
   //...
   }
  next(action);
};

Обратите внимание на использование ключевого слова async перед словом «действие». Пока это работает так, как ожидалось, я могу ожидать других асинхронных функций от этого промежуточного программного обеспечения. Однако, поскольку я не смог найти документацию по этому поводу, мне было интересно, действительно ли то, что я сделал, действительно.

Спасибо


person roboris    schedule 08.10.2017    source источник
comment
внутренне вы на самом деле не делаете ничего другого, спасибо, позвоните после решения, поэтому я не понимаю, почему это не сработает.   -  person Icepickle    schedule 09.10.2017
comment
У нас есть несколько таких асинхронных функций промежуточного программного обеспечения, и недавно в результате этого мы начали сталкиваться с неожиданным поведением. Мы видели, как селекторы избыточности срабатывали со старыми частями состояния, предположительно потому, что асинхронные промежуточные функции влияли на порядок, в котором обрабатывались действия.   -  person Tom    schedule 29.11.2020


Ответы (1)


Вы не думали изучить Redux Sagas? https://redux-saga.js.org/

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

Ваш код является действительным javascript, но вы можете столкнуться с несогласованностью состояния из-за асинхронного характера ваших функций.

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

Такое поведение может вызвать проблемы, подобные описанным вами.


Изменить: после того, как я узнал, что вы уже используете редукторы

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

Пример того, как связать действия с редукционными преобразователями из этой статьи: https://blog.jscrambler.com/async-dispatch-chaining-with-redux-thunk/

const dispatchChaining = () => async (dispatch) => {
  await Promise.all([
    dispatch(loadPosts()), // <-- async dispatch chaining in action
    dispatch(loadProfile())
  ]);

  return dispatch(updateDone());
};

const actions = redux.bindActionCreators({dispatchChaining}, store.dispatch);
actions.dispatchChaining().then(() => unsubscribe());

Обратите внимание, что до тех пор, пока есть возврат, эти отправки доступны. Преимущество здесь в том, что мы можем запускать асинхронные отправки параллельно и ждать завершения обоих. Затем обновите isDone, зная, что оба вызова выполняются без какого-либо непредсказуемого поведения. Эти многоразовые преобразователи могут находиться в разных частях магазина, чтобы поддерживать разделение задач.

person Bjørn Nyborg    schedule 03.12.2020
comment
Эй, Бьорн, твое объяснение того, почему происходит это странное поведение, верно. Однако мы уже используем redux-thunk для наших асинхронных действий. Проблема в том, что здесь мы не пытаемся отправить асинхронное действие, мы пытаемся создать асинхронное промежуточное ПО, которое может задержать выполнение действия. Имеет ли это смысл? - person Tom; 04.12.2020
comment
@Привет, Том! Обновленный ответ с возможным решением с использованием избыточных преобразователей. :) - person Bjørn Nyborg; 04.12.2020
comment
Спасибо, Бьорн. Это объясняет, как создавать новые действия, которые связывают другие асинхронные действия, но проблема в том, что мы пытаемся создать асинхронное промежуточное ПО. Наш вариант использования — это промежуточное программное обеспечение, которое гарантирует, что мы аутентифицируемся перед выполнением любых избыточных действий, требующих аутентификации. Если мы не аутентифицированы, все избыточные действия должны быть остановлены до тех пор, пока мы не будем аутентифицированы, а затем действия должны возобновиться как обычно. Мы пытаемся добиться остановки действий с помощью асинхронной промежуточной функции (не действия). - person Tom; 05.12.2020
comment
@Tom Я могу показаться хромым, но не могли бы вы объяснить значение «селекторов избыточности, запускаемых со старыми частями состояния», потому что селекторы должны запускаться только при изменении соответствующей части дерева состояний, которая является единственным источником истины. - person deepanshu; 07.12.2020
comment
@deepanshu - это не то, что сказал Бьорн в своем коде, это действительный javascript, но вы можете столкнуться с несогласованностью состояния из-за асинхронного характера ваших функций. Если ваше асинхронное действие не завершено до отправки следующего действия, второе действие будет использовать версию состояния, которая может быть изменена первым действием во время выполнения. ? - person Tom; 08.12.2020
comment
@ Том, извините, что снова вас беспокою, но ваша проблема в том, что ваши селекторы запускаются с одним и тем же значением состояния, например если состояние=1, то они снова вызываются с состоянием=1. - person deepanshu; 09.12.2020
comment
селекторы запускаются со старым значением, поэтому, если состояние = 1, затем состояние = 2, селектор может запускаться с состоянием = 1, где должно быть 2 - person Tom; 10.12.2020