Javascript 在redux thunk发货后从商店退还承诺

Javascript 在redux thunk发货后从商店退还承诺,javascript,redux,redux-thunk,Javascript,Redux,Redux Thunk,我正试图和redux thunk联系发送 function simple_action(){ return {type: "SIMPLE_ACTION"} } export function async_action(){ return function(dispatch, getState){ return dispatch(simple_action).then(()=>{...}); } } 我如何从商店获得退货通知 更具体地说: 我可能只是不理解这里的内容,

我正试图和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
),它显然返回一个
承诺

我特别想要的是当我向商店发送一个操作时:如何确保商店在上面的函数
action\u creator()
中发生任何其他事情之前完全处理了该操作


理想情况下,我希望商店能够返回某种承诺,但我不知道这是如何发生的,也不知道发生在哪里?

这里有一个关于如何调度和链接异步操作的示例

thunk中间件知道如何将thunk异步操作转换为操作,因此您只需将简单的_action()设置为thunk,如果中间件看到正常操作,thunk中间件将为您完成这项工作,他会将此操作作为普通操作分派,但如果它是异步函数,则会将您的异步操作转变为普通操作

因此,您的简单_操作需要是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函数时,可以使用dispatch函数

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!');
});
下面是一个完整的示例,说明如何编写动作创建者,从其他动作创建者那里调度动作和异步动作,并使用承诺构建控制流

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()之前调度此简单的_操作我在代码中添加了此注释。
//在开始下面的下一个操作之前执行此操作。

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

正如@Aaleks提到的,如果你的行为是一个
thunk
,你可以创建一个场景,返回一个
承诺
,然后你可以按照你提到的去做


顺便说一句,我认为命名你的
thunk
action\u creator
有点误导,因为
simple\u 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'))
时,它返回一个
Promise
对象,您可以将进一步的操作链接到该对象。

您需要做的是创建返回Promise的trunkate操作。dispatch函数返回您作为参数添加到它的调用中的内容。例如,如果希望dispatch返回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(() => {});

对我来说,这是行不通的。如果我想在
store.dispatch()之后调用
then
,我会得到一个
TypeError:无法读取未定义的
的属性'then'。我的行为肯定会回报你一个承诺。你注册了吗?安装部分您是否注册了thunk中间件?你能提供一些代码看看问题出在哪里吗?内联代码会很混乱。原则上,我有一个thunk,它返回一个promise函数调用,这反过来又返回一个promise。所以发生的是
store.dispatch->thunkAction->getStatusApi->store.dispatch()。然后->myAsyncApiCall->finalAction->reducer
。我总是从每个承诺/函数中返回,我不知道为什么它不等待myAsyncApiCall解决。问题解决了。丹·阿布拉莫夫指出,使用setTimeout是行不通的,我只是错过了在我的商店包装中返回分派。不管怎样,谢谢你的帮助和时间。有趣的+1技巧。简单而有力的奇妙,正是我所需要的。。出于好奇,这种模式有什么缺点吗?@JohnDetlefs真棒!我没发现。它的性能可能不如同步解决方案。我基本上到处都用。它有助于强制执行我现在使用的一个通用约定,其中状态修饰符(即操作)是特定的承诺,而状态分析是常规的同步getter。这种方式有助于加强分离和一致性。@Mapsy-Ta对于后续内容,喜欢这种模式,我想从现在起我会使用很多。由于实现简单,我们采用了相同的方法。您可以返回Promise resolve或reject,让调用方执行then for resolve、catch for reject,这对我来说维护了链。同时,您将返回包含来自api的可能负载的分派对象。但是,不确定这是否符合最佳实践。任何人我有点不喜欢调用方在then()中处理成功/失败的想法。失败应该在catch中处理。