Redux Thunk - 级联调度调用

问题描述

在我的 React Redux 项目中,我正在编写一个 thunk,并希望它仅在上一个更新(如果有的话)完成时才分派。我知道 thunk 是帮助我们延迟将操作分派到 reducer 的方法,它们也可以是异步的。这是我的 thunk 现在的样子:

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

但是我如何才能在上一次调用/状态更新完成后才调用调度

解决方法

只要您的 thunk 返回一个 promise:(dispatch,getState)=>Promise,您就可以组合并等待 thunk 完成。

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]));
,

这是您需要做的:


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
    })
  }) 
}