我正在使用redux和thunk中间件做出反应。我想做一个异步请求,然后进行一系列操作。然后它会以同步顺序发生。我无法实现它。
以下是我尝试过的两种方式:
addStudent(name, campusId = undefined, view = 'students') {
const creatingStudent = axios.post('/api/student', { name: name, campusId: campusId })
.then(res => {
return res.data
})
.then(student => {
return store.dispatch(createStudent(student))
})
.then(()=> {return store.dispatch(getStudents())})
.then(()=> {return store.dispatch(changeView(view))})
.catch(err => console.log(err))
addStudent(name, campusId = undefined, view = 'students') {
const creatingStudent = axios.post('/api/student', { name: name, campusId: campusId })
.then(res => {
return res.data
})
.then(student => {
store.dispatch(createStudent(student))
store.dispatch(getStudents())
store.dispatch(changeView(view))
})
.catch(err => console.log(err))
}
我想要订单: 1)axios请求 2)调度createStudent 3)派遣getStudents 4)调度changeView
但我安装了日志中间件,3和4总是颠倒过来。另外,特别是对于第二个选项,我偶尔会遇到一个致命的错误,我认为这是由于其他一些顺序的反转造成的,但我无法准确说出是什么顺序,因为应用程序在记录之前就崩溃了。
我还尝试将调用链接到彼此之间,但这似乎不起作用,可能是因为他们没有返回承诺。
这是我的getStudents动作创建者:
export const getStudents = () => {
return dispatch => {
axios.get('/api/students')
.then(response => {
return dispatch(receiveStudents(response.data));
});
}
};
因为它击中服务器所以它需要更长的时间才有意义,但是如果store.dispatch没有返回一个承诺,我该怎么办呢?然后关闭它?什么是正确的方法?
编辑:这最初没有明确说明。我应该更明确地表示,我的挫败感是在receiveStudents()之前调度了changeViews(),而不是像我暗示的那样,在getStudents()之前调度了changeViews()。我不知道什么时候发送了getStudents()。
答案 0 :(得分:0)
当我遇到这个问题https://github.com/reactjs/redux/issues/723时,这次谈话给了我很多帮助。
你应该可以用axios做这样的事情:
axios.all([
store.dispatch(createStudent(student)),
store.dispatch(getStudents()),
store.dispatch(changeView(view))
]).then(() => {
console.log('I did everything!');
});
您可以在每次发送链接操作后使用.then。我看到你说你试过了,但是这个设置直接来自redux-thunk中间件github自述文件,应该适用于你的案例https://github.com/gaearon/redux-thunk:
return dispatch(
makeASandwichWithSecretSauce('My Grandma')
).then(() =>
Promise.all([
dispatch(makeASandwichWithSecretSauce('Me')),
dispatch(makeASandwichWithSecretSauce('My wife'))
])
).then(() =>
dispatch(makeASandwichWithSecretSauce('Our kids'))
).then(() => //Chain another dispatch
dispatch(getState().myMoney > 42 ?
withdrawMoney(42) :
apologize('Me', 'The Sandwich Shop')
)
);
答案 1 :(得分:0)
我正在回答我自己的问题。我问这个问题的方式的一个方面是误导。我想让我的学生改变视图后,我感到很沮丧,因为我在记录中间件中看到了CHANGE_VIEW,然后是RECEIVE_STUDENTS。但这与说3和4相反是不一样的。事实上,3和4按顺序发送。我现在明白了,因为getStudents()本身是一个异步操作, dispatching 它将在异步操作完成之前解析。因此,即使按顺序调度getStudents()和changeView(),也会在changeView()之后调度receiveStudents()。在我的例子中,如果我想在receiveStudents()之后调度changeView(),我需要在getStudents()中调度(changeView())。
这是完成我想要的重构代码:
addStudent(student, view = 'students') {
const creatingStudent = axios.post('/api/student', student)
.then(res => res.data)
.then(student => store.dispatch(createStudent(student)))
.then(()=> store.dispatch(getStudents(view)))
.catch(err => console.log(err))
}
const getStudents = (view) => {
return dispatch => {
axios.get('/api/students')
.then(res => dispatch(receiveStudents(res.data)))
.then(()=>dispatch(changeView(view)))
}
}