[英]How can I make redux dispatch an action as well as return a promise?
這是我在songAction.js中的功能
export function createSong(title, url, token) {
axios.defaults.headers.common['Authorization'] = token
return function (dispatch) {
axios.post('http://localhost:8080/api/song/create', {
title,
link: url
})
.then((response) => {
console.log('the response was', response)
if(response.data.success){
dispatch({type: "CREATE_SONG_FULFILLED", payload: response.data.song})
} else {
dispatch({type: "CREATE_SONG_REJECTED", payload: response.data})
}
})
.catch((err) => {
dispatch({type: "CREATE_SONG_REJECTED", payload: err})
})
}
}
我希望能夠在調度后返回一個promise,這樣我就可以在組件中使用這樣的函數 -
createSong(title, url, token)
.then((result) =>{
// do stuff with result
})
我知道我可以通過回調來使這個工作異步..但我想使用承諾的ES6功能。 我有點困惑,我怎么能這樣做。
如果你想要完整的ES6,你應該使用async/await
語法。 這消除了根本不需要處理承諾的需要。
export function createSong (title, url, token) {
axios.defaults.headers.common['Authorization'] = token
return async (dispatch) => {
try {
const response = await axios.post('http://localhost:8080/api/song/create', {
title,
link: url
})
console.log('the response was', response)
if (response.data.success) {
dispatch({type: 'CREATE_SONG_FULFILLED', payload: response.data.song})
} else {
dispatch({type: 'CREATE_SONG_REJECTED', payload: response.data})
}
} catch (err) {
dispatch({type: 'CREATE_SONG_REJECTED', payload: err})
}
}
}
createSong
返回的匿名函數標有新的async
關鍵字。 這意味着匿名函數現在將返回隱式Promise。
async
關鍵字還允許您在函數體中使用await
,以便await
對axios.post
的異步調用, axios.post
其視為同步調用。
另一個優點是你可以回到使用普通的try / catch
塊。 這些實際上是在解決和拒絕幕后的隱含承諾,但它們以正常的方式行事。
因為匿名函數實際上返回一個Promise,在調用鏈的createSong(...)
,無論你在哪里調用createSong(...)
函數,你也可以使用async / await
語法......等等。 沒有更多的回調,也沒有更明確的Promise處理。
首先,您需要返回axios
調用。
...
return function (dispatch) {
return axios.post('http://localhost:8080/api/song/create', {
title,
link: url
})
...
你的createSong
函數正在返回另一個函數(所以它是一個curried函數)。
因此,
createSong(title, url, token)(dispatch)
.then(()=>{
// something
})
看起來對我很有效。
我認為使用調度操作的返回值並不是非常“反應”的方法。
有一種更好的方法可以解決使用Redux Saga這樣的“復雜”情況,例如這里 。
雖然,我過去以這種方式通過調度操作使用返回值:
export const updatePage = (id, batch) => {
return dispatch => {
dispatch({
type: 'UPDATE_PAGE',
payload: {
id
}
})
// Make an API call
return requestUpdatePages(
id, batch
).then(data => {
// When API call is successful
return dispatch({
type: 'UPDATE_PAGE_SUCCESS',
payload: {
id,
data
})
})
.catch(error => {
// When API call fails
return dispatch({
type: 'UPDATE_PAGE_FAIL',
payload: {
error,
id
},
error: true
})
})
}
}
// After dispatch is bound to action creators
// you can use it like this
handleClick(id) {
const { updatePage } = this.props
updatePage(id).then(action => {
if(action.type === 'UPDATE_PAGE_SUCCESS') {
console.log('Whee, page has been updated!', action.payload.data)
} else {
console.error('Something went wrong :-( ', action.payload.error)
}
})
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.