Javascript-Redux操作不会连续运行

时间:2019-01-09 16:06:02

标签: javascript reactjs redux queue action

我遇到需要连续运行2个Redux Action的情况。 上下文是用户单击“预览”按钮,我想显示一个加载器,直到完成拼图为止。

function mapDispatchToProps(dispatch) {
  return {
    onPreview: () => {
      dispatch(generatePreview());
    },
  };
}

为此,我使用了中间件redux-thunk,首先要执行的操作返回一个Promise.resolve(),第二个操作在then()中:

export function generatingPreview() {
  return dispatch => {
    dispatch({
      type: GENERATING_PREVIEW,
    });
    return Promise.resolve();
  };
}

export function generatePreview() {
  return (dispatch, getState) => {
    dispatch(generatingPreview()).then(() => {
      const state = getState();
      const conf = state.getIn(['login', 'conf']).toJS();
      const wordList = state.getIn(['login', 'wordList']);
      try {
        const newPuzzle = Wordfind.newPuzzleLax(wordList, conf);
        dispatch(generatePreviewSuccess(newPuzzle));
      } catch (err) {
        dispatch(generatePreviewError(err.message));
      }
    });
  };
}

export function generatePreviewError(error) {
  return {
    type: GENERATE_PREVIEW_ERROR,
    error,
  };
}

export function generatePreviewSuccess(payload) {
  return {
    type: GENERATE_PREVIEW_SUCCESS,
    payload,
  };
}

不幸的是,加载程序从未出现。我在console.logged组件渲染时将状态设置为true,并将其更改!我可以看到日志,但看不到加载程序,组件只有在分派动作generatePreviewSuccess()generatePreviewError()之后才真正重新呈现。而且对于加载器而言,这不是问题,如果我用循环替换newPuzzleLax函数以腾出足够的时间来查看它,那么我就能看到它!

我的理论是,我用来生成谜题的函数Wordfind.newPuzzleLax(wordList, conf)阻止了操作队列,因为在Chrome Redux工具上,我看到第一个操作与第二个操作同时出现: Link to the function

enter image description here

如果我在两个动作的派发之间添加了1微秒的延迟,则会出现加载程序...但是我真的很想了解发生了什么。先感谢您。如果有帮助,我可以使用react-boilerplate

我还尝试通过执行以下操作将生成拼图的函数转换为异步拼图:

const wordFindAsync = async (wordList, conf) =>
  Wordfind.newPuzzleLax(wordList, conf);

export function generatePreview() {
  return (dispatch, getState) => {
    dispatch(generatingPreview())
      .then(() => {
        const state = getState();
        const conf = state.getIn(['login', 'conf']).toJS();
        const wordList = state.getIn(['login', 'wordList']);
        wordFindAsync(wordList, conf);
      })
      .then(res => dispatch(generatePreviewSuccess(res)))
      .catch(err => {
        dispatch(generatePreviewError(err.message));
      });
  };
}

1 个答案:

答案 0 :(得分:0)

在第二个版本中,您没有将Promise从wordFindAsync(wordList, conf)返回到原始Promise链中,因此下一个then之前,它没有得到解决/等待。

export function generatePreview() {
  return (dispatch, getState) => {
    dispatch(generatingPreview())
      .then(() => {
        const state = getState();
        const conf = state.getIn(['login', 'conf']).toJS();
        const wordList = state.getIn(['login', 'wordList']);
        return wordFindAsync(wordList, conf); //  return your promise here 
      })
      .then(res => dispatch(generatePreviewSuccess(res)))
      .catch(err => {
        dispatch(generatePreviewError(err.message));
      });
  };
}

这是演示我所指行为的简单示例。

这将只等待1秒钟,直到记录“完成”:

const waitOneSec = () =>
  new Promise(resolve => {
    console.log("waiting 1 secoond");
    setTimeout(resolve, 1000);
  });

waitOneSec()
  .then(() => {
    waitOneSec(); // Promise not returned
  })
  .then(() => console.log("done"));

这将等待2秒钟,直到记录“完成”:

const waitOneSec = () =>
  new Promise(resolve => {
    console.log("waiting 1 secoond");
    setTimeout(resolve, 1000);
  });

waitOneSec()
  .then(() => {
    return waitOneSec(); //  Promise returned
  })
  .then(() => console.log("done"));

希望有帮助。