首页 文章

在redux thunk dispatch之后从商店返回承诺

提问于
浏览
34

我正在尝试用redux thunk链接调度

function simple_action(){
  return {type: "SIMPLE_ACTION"}
}

export function async_action(){
  return function(dispatch, getState){
    return dispatch(simple_action).then(()=>{...});
  }
}

如何让调度从商店返回承诺?

进一步来说:

我可能只是在这里不了解一些东西,但是在 redux-thunk 的所有示例中,它们都调用了一个单独的异步事件(如 fetch ),这显然会返回一个 Promise .

我特别想要的是当我向商店发送一个动作时:在上面的函数 action_creator() 之前,如何确定商店已经完全处理了该动作 .

理想情况下,我希望商店能够返回某种承诺,但我不明白这是怎么回事?

3 回答

  • 3

    这里有一个关于如何分派和链接异步操作的示例 . https://github.com/gaearon/redux-thunk

    thunk中间件知道如何将thunk异步操作转换为动作,所以你必须让你的simple_action()成为thunk并且thunk中间件将为你完成这项工作,如果中间件看到正常动作,他将派遣这个操作为正常操作,但如果它是异步功能,则会将异步操作转换为正常操作 .

    所以你的simple_action需要是一个thunk(thunk是一个返回一个函数的函数 . )例如:

    function makeASandwichWithSecretSauce(forPerson) {
      return function (dispatch) {
        return fetchSecretSauce().then(
          sauce => dispatch(makeASandwich(forPerson, sauce)),
          error => dispatch(apologize('The Sandwich Shop', forPerson, error))
        );
      };
    }
    

    使用makeASandwichWithSecretSauce函数时,您可以使用调度函数

    store.dispatch(
      makeASandwichWithSecretSauce('Me')
    );
    

    乃至

    // It even takes care to return the thunk’s return value
    // from the dispatch, so I can chain Promises as long as I return them.
    
    store.dispatch(
      makeASandwichWithSecretSauce('My wife')
    ).then(() => {
      console.log('Done!');
    });
    

    这里有一个完整的例子,说明如何编写动作创建者,从其他动作创建者发送动作和异步动作,并使用Promises构建控制流 .

    function makeSandwichesForEverybody() {
      return function (dispatch, getState) {
        if (!getState().sandwiches.isShopOpen) {
          // You don’t have to return Promises, but it’s a handy convention
          // so the caller can always call .then() on async dispatch result.
          return Promise.resolve();
        }
    
        //Do this action before starting the next one below 
        dispatch(simple_action());
    
        // We can dispatch both plain object actions and other thunks,
        // which lets us compose the asynchronous actions in a single flow.
        return dispatch(
          makeASandwichWithSecretSauce('My Grandma')
        ).then(() =>
          Promise.all([
            dispatch(makeASandwichWithSecretSauce('Me')),
            dispatch(makeASandwichWithSecretSauce('My wife'))
          ])
        ).then(() =>
          dispatch(makeASandwichWithSecretSauce('Our kids'))
        ).then(() =>
          dispatch(getState().myMoney > 42 ?
            withdrawMoney(42) :
            apologize('Me', 'The Sandwich Shop')
          )
        );
      };
    }
    //apologize and withdrawMoney are simple action like this for example
          return {
            type:  "END_SUCESS"
          }
    

    //用法

    store.dispatch(
      makeSandwichesForEverybody()
    ).then(() =>
        console.log("Done !");
    );
    

    要创建自己的承诺,您可以使用像bluebird这样的库 .

    //编辑:为了确保商店在函数action_creator()中发生任何其他事情之前完全处理了该操作,您可以在action_creator()之前调度此simple_action; //我将此评论添加到代码 //Do this action before starting the next one below

  • 3

    dispatch 将返回它调用的动作/函数返回的内容;因此,如果您想链接某些活动(根据您的示例),您的操作将需要返回 Promise .

    正如@Aaleks所提到的,如果您的行为是 thunk ,您可以创建一个返回 Promise 的场景,那么您可以按照您的提及进行操作 .

    BTW我认为命名你的 thunk action_creator 有点误导,因为 simple_action 实际上是Redux用语中的动作创建者 - 已相应编辑:)

  • 22

    这是我最近一直在使用的模式:

    export const someThenableThunk = someData => (dispatch, getState) => Promise.resolve().then(() => {
      const { someReducer } = getState();
      return dispatch({
        type: actionTypes.SOME_ACTION_TYPE,
        someData,
      });
    });
    

    当你 dispatch(someThenableThunk('hello-world')) 时,它返回一个 Promise 对象,你可以将进一步的动作链接到 .

相关问题