我遇到需要连续运行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。
如果我在两个动作的派发之间添加了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));
});
};
}
答案 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"));
希望有帮助。