react redux - 应用 "fetch" 并在调度内部调度失败
react redux - applying a "fetch" and dispatch inside of a dispatch fails
我有一个工作操作可以通过简单的调用 "saveJwt(data)".
保存 JWT 令牌
动作如下:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({type: REQUEST_LOGIN_TOKEN, payload: username})
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({type: RECEIVE_LOGIN_TOKEN, payload: data})
saveJwt(data)
})
.catch(error => {
clearJwt()
dispatch({type: ERROR_LOGIN_TOKEN, payload: error.message})
})
addTask(task)
return task
}
然后我在"saveJwt(data)"下面加入了这段代码:
if (!confirmSelectDataExistance()) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
})
}
所有它应该做的就是检查项目是否在本地存储中,如果是,这次在添加 JWT 的情况下再次获取。
这是完成的操作,因此您可以看到它所在的位置:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
//selectData download if nothing is local storage.
if (!confirmSelectDataExistance()) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
})
}
})
.catch(error => {
clearJwt()
dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
})
addTask(task)
return task
}
所以现在我的第一次获取以未定义的承诺结束,它只是跳到底部,任务的值为未定义,
你会相信昨天它运行完美,而当我今天尝试它时却失败了。
为什么那个代码块导致整个事情失败..我把它注释掉并且它工作正常..
我怀疑它与两个承诺等有关,但必须有一种正确的方法来管理它。我本以为如果它要保存 JWT 令牌,那将表明它已完成第一次下载但是其他地方出了问题...在那段代码中或者更可能是它的使用方式。
假设 confirmSelectDataExistance 是异步的并且 returns 承诺并且承诺 retrieveSelectData 必须在 requestLoginToken 之前解决,解决方案可能是:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
//selectData download if nothing is local storage.
return confirmSelectDataExistance().then(isConfirmed => {
if (!isConfirmed) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
});
return retrieveSelectData;
}
})
})
.catch(error => {
clearJwt()
dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
})
addTask(task)
return task
}
如果 saveSelectData 也是异步的,您应该改为调用
return saveSelectData(selectData);
我有一个工作操作可以通过简单的调用 "saveJwt(data)".
保存 JWT 令牌动作如下:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({type: REQUEST_LOGIN_TOKEN, payload: username})
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({type: RECEIVE_LOGIN_TOKEN, payload: data})
saveJwt(data)
})
.catch(error => {
clearJwt()
dispatch({type: ERROR_LOGIN_TOKEN, payload: error.message})
})
addTask(task)
return task
}
然后我在"saveJwt(data)"下面加入了这段代码:
if (!confirmSelectDataExistance()) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
})
}
所有它应该做的就是检查项目是否在本地存储中,如果是,这次在添加 JWT 的情况下再次获取。
这是完成的操作,因此您可以看到它所在的位置:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
//selectData download if nothing is local storage.
if (!confirmSelectDataExistance()) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
})
}
})
.catch(error => {
clearJwt()
dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
})
addTask(task)
return task
}
所以现在我的第一次获取以未定义的承诺结束,它只是跳到底部,任务的值为未定义,
你会相信昨天它运行完美,而当我今天尝试它时却失败了。
为什么那个代码块导致整个事情失败..我把它注释掉并且它工作正常..
我怀疑它与两个承诺等有关,但必须有一种正确的方法来管理它。我本以为如果它要保存 JWT 令牌,那将表明它已完成第一次下载但是其他地方出了问题...在那段代码中或者更可能是它的使用方式。
假设 confirmSelectDataExistance 是异步的并且 returns 承诺并且承诺 retrieveSelectData 必须在 requestLoginToken 之前解决,解决方案可能是:
export const requestLoginToken = (username, password) =>
(dispatch, getState) => {
dispatch({ type: REQUEST_LOGIN_TOKEN, payload: username })
const payload = {
userName: username,
password: password,
}
const task = fetch('/api/jwt', {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(data => {
dispatch({ type: RECEIVE_LOGIN_TOKEN, payload: data })
saveJwt(data)
//selectData download if nothing is local storage.
return confirmSelectDataExistance().then(isConfirmed => {
if (!isConfirmed) {
dispatch({ type: REQUEST_SELECT_DATA })
const token = getJwt()
const headers = new Headers({
'Authorization': `Bearer ${token}`
})
const retrieveSelectData = fetch('/api/SelectData/SelectData', {
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
})
.then(handleErrors)
.then(response => response.json())
.then(selectData => {
dispatch({ type: RECEIVE_SELECT_DATA, payload: selectData })
saveSelectData(selectData)
});
return retrieveSelectData;
}
})
})
.catch(error => {
clearJwt()
dispatch({ type: ERROR_LOGIN_TOKEN, payload: error.message })
})
addTask(task)
return task
}
如果 saveSelectData 也是异步的,您应该改为调用
return saveSelectData(selectData);