return 在 redux thunk dispatch 后从商店承诺

return promise from store after redux thunk dispatch

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

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

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

我如何从商店获得 return 的承诺?

更具体地说:

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

我特别要寻找的是当我向商店发送一个动作时:如何确保在上面的函数 action_creator() 中发生任何其他事情之前,商店已经完全处理了该动作。

理想情况下,我希望商店 return 做出某种承诺,但我不明白这是如何或在哪里发生的?

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

thunk 中间件知道如何将 thunk 异步操作转换为操作,因此您只需让 simple_action() 成为一个 thunk,thunk 中间件会为您完成这项工作,如果中间件看到一个正常的动作,他会把这个动作作为正常动作发送,但如果它是一个异步函数,它会将你的异步动作变成正常动作。

所以你的 simple_action 需要是一个 thunk(一个 thunk 是一个 returns 函数的函数。)例如:

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

dispatch 将 return 无论 action/function 它调用什么 return;因此,如果您想链接某些活动(根据您的示例),您的操作需要 return a Promise.

正如@Aaleks 提到的,如果你的行动是 thunk,你可以创建一个你 return 和 Promise 的场景,然后你可以按照你提到的去做。

顺便说一句,我认为命名您的 thunk action_creator 有点误导,因为 simple_action 实际上是 Redux 用语中的 Action Creator - 已进行相应编辑:)

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

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

当您 dispatch(someThenableThunk('hello-world')) 时,它 returns 一个 Promise 对象,您可以将进一步的操作链接到该对象。

您需要做的是创建returnS Promise 的trunkate 操作。调度函数 return 您作为参数添加到它的调用中的内容。例如,如果你想调度到 return Promise,你必须将 Promise 作为参数添加到调用中。

function simple_action() {
  return { type: 'SIMPLE_ACTION' };
}

export function async_action(dispatch, getState) {
  return function () {
    return Promise.resolve(dispatch(simple_action()));
  }
}

const boundAction = async_action(dispatch, getState);
boundAction().then(() => {});