拒绝后未完成的承诺
Promise not completing on rejection
所以我有一个使用以下功能提交的表单:
const formSubmit = async (formData) => {
const response = await SubmissionsResource.create(formData)
const { data, status } = response
console.log('Request completed.')
if (status === 201) {
toast.success('Submission created.')
} else {
toast.error('Something went wrong.')
console.error(data)
}
}
其中使用了以下内容:
const SubmissionsResource = {
create: ({ formData }) => (
Request.privatePost(apiUrl('submissions'), formData)
),
}
其中使用了以下内容:
export const Request = {
privateRequest: ({ data, method, params, url }) => {
axios.interceptors.request.use((request) => {
request.headers.authorization = getBearerToken()
return request
}, (error) => Promise.reject(error))
axios.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
// If request is coming from a sign in attempt
if (error.response.status === 401 && originalRequest.url.includes('auth/token')) {
return Promise.reject(error)
}
// If request is coming from elsewhere, assume token might be expired
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
const refresh_token = LocalStorageService.getRefreshToken()
const response = await axios.post(
`${API_BASE}/oauth/token`,
{ client_id, client_secret, grant_type: 'refresh_token', refresh_token }
)
if (response.status === 200) {
LocalStorageService.setUser(response.data)
axios.defaults.headers.common.Authorization = getBearerToken()
return axios(originalRequest)
}
return Promise.reject(error)
}
return Promise.reject(error)
}
)
return axios({ method, url, data, params })
},
privatePost: (url, data) => (
Request.privateRequest({ method: 'post', data, url })
)
}
当响应成功时,我总是看到“请求完成”日志,并且看到 toast.success
消息。但是,当请求失败时,我从未看到“请求已完成”日志,也没有看到 toast.error
消息。
如果响应未经授权返回(401 状态代码),axios 拦截器应该重试一次,它成功地做到了,并且在所有其他情况下,拒绝承诺和 return 错误。
Request.privateRequest
应该拒绝承诺和 return 到 Request.privatePost
的错误,这应该 return 返回到 SubmissionsResource.create
,然后最后到 formSubmit
。然而,它并没有完成承诺并 return 出现错误,它只是停止了整个功能并且永远不会进入“请求已完成”日志。
我假设这是由于我对 promises 的理解不正确,但我无法弄清楚那是什么。为什么承诺没有在 formSubmit
内完成并继续到下一行?
通过返回 Promise.reject(),您告诉 axios 拒绝网络请求返回的承诺,但调用代码没有捕获任何拒绝。
尝试 try-ing:
const formSubmit = async (formData) => {
try {
const response = await SubmissionsResource.create(formData)
const { data, status } = response
console.log('Request completed.');
toast.success('Submission created.')
} catch(error) {
if (error.response.status === 401)
toast.error('Bad news: 401.');
else
toast.error('Some other kind of bad news.');
}
}
所以我有一个使用以下功能提交的表单:
const formSubmit = async (formData) => {
const response = await SubmissionsResource.create(formData)
const { data, status } = response
console.log('Request completed.')
if (status === 201) {
toast.success('Submission created.')
} else {
toast.error('Something went wrong.')
console.error(data)
}
}
其中使用了以下内容:
const SubmissionsResource = {
create: ({ formData }) => (
Request.privatePost(apiUrl('submissions'), formData)
),
}
其中使用了以下内容:
export const Request = {
privateRequest: ({ data, method, params, url }) => {
axios.interceptors.request.use((request) => {
request.headers.authorization = getBearerToken()
return request
}, (error) => Promise.reject(error))
axios.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config
// If request is coming from a sign in attempt
if (error.response.status === 401 && originalRequest.url.includes('auth/token')) {
return Promise.reject(error)
}
// If request is coming from elsewhere, assume token might be expired
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
const refresh_token = LocalStorageService.getRefreshToken()
const response = await axios.post(
`${API_BASE}/oauth/token`,
{ client_id, client_secret, grant_type: 'refresh_token', refresh_token }
)
if (response.status === 200) {
LocalStorageService.setUser(response.data)
axios.defaults.headers.common.Authorization = getBearerToken()
return axios(originalRequest)
}
return Promise.reject(error)
}
return Promise.reject(error)
}
)
return axios({ method, url, data, params })
},
privatePost: (url, data) => (
Request.privateRequest({ method: 'post', data, url })
)
}
当响应成功时,我总是看到“请求完成”日志,并且看到 toast.success
消息。但是,当请求失败时,我从未看到“请求已完成”日志,也没有看到 toast.error
消息。
如果响应未经授权返回(401 状态代码),axios 拦截器应该重试一次,它成功地做到了,并且在所有其他情况下,拒绝承诺和 return 错误。
Request.privateRequest
应该拒绝承诺和 return 到 Request.privatePost
的错误,这应该 return 返回到 SubmissionsResource.create
,然后最后到 formSubmit
。然而,它并没有完成承诺并 return 出现错误,它只是停止了整个功能并且永远不会进入“请求已完成”日志。
我假设这是由于我对 promises 的理解不正确,但我无法弄清楚那是什么。为什么承诺没有在 formSubmit
内完成并继续到下一行?
通过返回 Promise.reject(),您告诉 axios 拒绝网络请求返回的承诺,但调用代码没有捕获任何拒绝。
尝试 try-ing:
const formSubmit = async (formData) => {
try {
const response = await SubmissionsResource.create(formData)
const { data, status } = response
console.log('Request completed.');
toast.success('Submission created.')
} catch(error) {
if (error.response.status === 401)
toast.error('Bad news: 401.');
else
toast.error('Some other kind of bad news.');
}
}