Уменьшение количества вызовов каскадной отправки

#redux #react-redux #redux-thunk #thunk

#сокращение #реагирование- сокращение #уменьшение количества вызовов #thunk

Вопрос:

В моем проекте React Redux я пишу thunk и хочу, чтобы он отправлялся только в том случае, если было завершено предыдущее обновление, если таковое было выполнено. Я знаю, что thunks — это методы, которые помогают нам задерживать отправку действий в редуктор, и они также могут быть асинхронными. Вот как выглядит мой thunk прямо сейчас:

 myThunkMethod = () => async (dispatch, getState) =>{
    dispatch(...my action...);
}
 

но я как могу вызвать отправку только после завершения предыдущего вызова / обновления состояния

Ответ №1:

Вот что вам нужно сделать:

 
const firstThunk = () => (dispatch, getState) => {
  // do or dispatch something here
  return Promise.resoleved("first thunk resolved");
}

const secondThunk = () => (dispatch, getState) => {
  // do or dispatch something here
  return Promise.resolved("second thunk resolved")
}

const thirdThunk = () => (dispatch, getState) => {
  // I want to first dispatch the first thunk
  dispatch(firstThunk()).then(result => {
    // first thunk successfully dispatched now it's time for secondThunk
    dispatch(secondThunk()).then(res => {
      // here both firstThunk and secondThunk dispatched successfully
    })
  }) 
}
 

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

1. спасибо за ваши усилия, но вместо thunk A, B .. и что-то конечное, я имел в виду что-то вроде: A-> A-> A-> …..-> A, где A — тот же thunk, но отправка происходит только после завершения предыдущего вызова

Ответ №2:

Вы можете комбинировать и ждать завершения выполнения, пока ваш thunk возвращает обещание : (dispatch,getState)=>Promise .

 const thunkA = (arg) => (dispatch, getState) => {
  //do stuff and RETURN PROMISE
  return Promise;
};
const thunkB = (arg) => (dispatch, getState) => {
  //do stuff and RETURN PROMISE
  return Promise;
};
//combined thunk
const combinedThunk = (arg) => (dispatch, getState) =>
  tunkA(arg)(dispatch, getState).then(() =>
    thunkB(arg)(dispatch, getState)
  );
//from component
const Component = () => {
  const dispatch = React.useDispatch();
  React.useEffect(() => {
    dispatch(thunkA("some arg")).then(() =>
      dispatch(thunkB("someArg"))
    );
  }, [dispatch]);
};
 

Вот как вы можете выполнить рекурсивный thunk:

 const recursiveThunk = (times) => (dispatch, getState) => {
  if (times === 0) {
    return;
  }
  dispatch(started());
  somePromise().then(
    (result) => {
      dispatch(success());
      return recursiveThunk(times - 1)(dispatch, getState);
    },
    (reject) => dispatch(failed())
  );
};
 

Неясно, что вы хотите в своем вопросе и своем комментарии, но если вы хотите каждый раз вызывать thunkA с элементом из массива в качестве параметра, вы можете сделать это:

 const combinedThunk = (args) => (dispatch, getState) => {
  if (args.length === 0) {
    return;
  }
  return tunkA(args[0])(dispatch, getState).then(
    () => combinedThunk(args.slice(1))(dispatch, getState),
    (reject) => dispatch(failed(reject))
  );
};
//call thunkA with 1, then 2 and then 3
dispatch(combinedThunk([1, 2, 3]));
 

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

1. спасибо за ваши усилия, но вместо thunk A, B .. и что-то конечное, я имел в виду что-то вроде: A-> A-> A-> …..-> A, где A — тот же thunk, но отправка происходит только после завершения предыдущего вызова

2. @DivyanshGoenka Итак, вам нужен рекурсивный thunk, я добавил его в ответ.