拒绝后未完成的承诺

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.');
  }
}