Redux Toolkit: типы действий жизненного цикла не синхронизируются при отправке нескольких асинхронных действий в одном потоке

#javascript #reactjs #typescript #redux #redux-toolkit

#javascript #reactjs #typescript #сокращение #переопределение-инструментарий #redux-toolkit

Вопрос:

У меня есть асинхронное последовательное действие для организации нескольких асинхронных действий, подобных этому

 const someAction = createAsyncThunk(
  'my/someAction',
  async () => {...}
)
const someAction2 = createAsyncThunk(
  'my/someAction2',
  async () => {...}
)
const generatedThunk = createAsyncThunk(
  'my/thunk',
  async (arg, thunkApi) => {
    thunkApi.dispatch(someAction());
    thunkApi.dispatch(someAction2());
  }
)
  

Я обнаружил, что любой из асинхронных запросов, т.е. someAction и someAction отклоненных, my/thunk все равно будет выполнен. Как я могу сделать my/thunk отклоненным, когда любой из thunks отклоняет?

Ответ №1:

createAsyncThunk всегда фиксирует ошибки, чтобы мы не получали сообщения об отклонении невыполненного обещания в вашем приложении.

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

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

Одним из вариантов здесь было бы:

 return Promise.all([
  thunkApi.dispatch(someAction()).then(unwrapResult),
  thunkApi.dispatch(someAction2()).then(unwrapResult)
]);
  

Это приведет:

  • Запускайте оба действия параллельно
  • Преобразуйте действие результата каждого действия обратно в выполненное или отклоненное обещание
  • Возвращает обещание, которое отклонит, если любой из этих запросов отклонен

Комментарии:

1. Привет, спасибо за ответ! На самом деле someAction и someAction2 не параллельны, someAction2 будут выполняться только при возникновении определенной ошибки во время someAction , я значительно упрощаю код, чтобы он выглядел так, как будто они параллельны. Если мы рассмотрим только одно из них здесь, как я спрашивал, я хочу 'my/thunk' отклонять, когда 'my/someAction' or мой / someAction2` отклоняет, мне нужно вернуть обещание, которое отклонит. Интересно, могли бы вы добавить фрагмент кода в свой ответ, чтобы показать мне, как это сделать? Спасибо!

2. кстати, как вы сказали, если мне нужно выполнить эти действия последовательно, мне нужно await . Интересно, есть ли какие-либо другие способы, которые используют статические методы на Promise подобных Promise.all (я знаю, Promise.all что в этом случае это не работает)

Ответ №2:

Проверьте результат вашего дочернего действия, и просто throw a new Error там, ваше основное действие автоматически перехватит это. И завершится reject .

Пример: введите описание изображения здесь

или, если ваши типы правильно настроены, вы можете уничтожить объект error и выполнить проверку ошибки следующим образом: if(error) throw Error('Some message!') ;

Комментарии:

1. дочернее действие возвращает обещание, когда обещание разрешается, дочернее действие будет fulfilled , а когда обещание отклоняется, действие будет rejected

2. Вам нужно использовать await , иначе ваше основное действие не будет ждать своего дочернего действия и выполнит возврат до того, как дочернее действие будет выполнено или отклонено.

3. Я пытался await выполнить дочерние действия, но все еще не получил rejected для основного действия, когда дочернее действие было отклонено. Мое дочернее действие действительно похоже на это export const action = createAsyncThunk("action",async () => { return Promise.reject("reject"); } . Но unwrapResult решает проблему