Redux Thunk同步操作不同步

时间:2018-08-28 14:08:29

标签: reactjs redux promise react-redux redux-thunk

我正在将React / Redux用于正在构建的应用程序,并且正在尝试实施一项操作以注销用户。我的应用程序具有可以编辑的工件。我希望我的应用程序先保存工件,然后注销用户,这将清除商店。我已经使用Redux Thunk实现了以下步骤:

export function logoutUser(artifact) {
  return (dispatch) => {
    dispatch(saveArtifact(artifact))
      .then(() => {
        dispatch(requestLogout());
        return axios.get(`${API_BASE}/auth/logout`)
          .then(() => dispatch(logoutSuccess()))
          .catch(error => dispatch(logoutFailure(error)));
      });
  };
}

我希望这样做可以保存工件,并且只有在保存工件后,才将用户注销。我的保存动作调用了另一个动作,该动作会在保存工件后加载它们,但这无关紧要。它应该返回一个Promise,然后才继续注销用户。

但是,这不是正在发生的事情。出于某种原因,我收到多个调用以保存工件(已验证它们来自此函数),然后调用异步发生,因此最后一次加载工件,因此注销后不会清除我的redux存储。 / p>

如果有人可以提供一些有关为什么发生这种情况以及我如何解决它的见解,我会很乐意。

其他信息:

我正在按如下方式清除root减速器中的redux存储:

const rootReducer = (state, action) => {
  let newState = state;
  if (action.type === types.LOGOUT_SUCCESS) {
    newState = undefined;
  }

  return appReducer(newState, action);
};

我将文物保存如下:

function sendSaveArtifactRequest(artifact) {
  if (artifact._id == null) {
    const artifactWithoutId = _.omit(artifact, ['_id']);
    return axios.post(`${API_BASE}/artifacts`, artifactWithoutId)
      .then(result => result.data);
  }

  return axios.put(`${API_BASE}/artifacts`, artifact).then(() => artifact);
}

export function saveArtifact(artifact) {
  return (dispatch) => {
    dispatch(requestSaveArtifact());

    return sendSaveArtifactRequest(artifact)
      .then(data => dispatch(saveArtifactSuccess(data)))
      .catch(error => dispatch(saveArtifactFailure(error)))
      .then(() => dispatch(loadArtifacts()));
  };
}

我正在加载工件,如下所示:

function sendArtifactsRequest() {
  return new Promise((resolve, reject) => {
    axios.get(`${API_BASE}/artifacts`)
      .then(result => resolve(result.data))
      .catch(error => reject(error));
  });
}

export function loadArtifacts() {
  return (dispatch) => {
    dispatch(requestArtifacts());

    return sendArtifactsRequest()
      .then(data => dispatch(loadArtifactsSuccess(data)))
      .catch(error => dispatch(loadArtifactsFailure(error)));
  };
}

1 个答案:

答案 0 :(得分:1)

我已经发现了问题,您的saveArtifact操作中有多个链接的承诺。在您的情况下,sendSaveArtifactRequest承诺解决之后,您分派了requestLogout,并在成功后清除了Redux状态。但是另一方面,还有一些未完成的承诺,您不必等待logoutUser行动中的解决方案。当您清除Redux存储时,您未决的Promise将得到解决,并再次更新Redux状态。 您可以在这里做两件事:

  • 在分发Promise.all().then()时使用saveArtifact,然后分发注销操作。
  • 您可以通过loadArtifacts操作注销用户,但是我不确定确切的用例,也许这不符合您的应用要求。但它总是在加载工件时调用。

最重要的是,请在您的应用程序中集成 Redux DevTools ,以便您可以跟踪调度动作的顺序。

在您的store.js

import { createStore, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import rootReducer from './reducers';

const enhancer = compose(
  applyMiddleware(thunk),
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
);

export default createStore(rootReducer, enhancer);

`