开发者问题收集

Axios POST 解析为未定义

2019-10-29
2388

我开始将我的项目从标准 Fetch API 切换到 Axios 库。Axios 看起来很棒,拥有所有拦截器、自定义实例等。问题始于 POST 请求。

我有一个自定义 axios 实例,定义为:

export const axiosInstance = axios.create({
  baseURL: API_URL,
  timeout: 10000
});

我将其用于大多数 API 调用,大多数都很好,除了一个让我非常沮丧地卡住了很长时间。 使用 POST 请求,似乎 Promise 被解析为 undefined 。 让我们看一个代码:

export async function saveIncomes(incomes) {
  const { added, changed } = incomes;
  const add_res = axiosInstance.post(`${INCOMES_URL}`, added).then(console.log);
  const change_responses = [];
  for (let changed_row of changed) {
    change_responses.push(
      axiosInstance.put(`${INCOMES_URL}${changed_row.id}/`, changed_row)
    );
  }
  let finalRes = [];
  try {
    finalRes = await axios.all([add_res, ...change_responses]);
  } catch (e) {
    console.log(e);
  }
  return finalRes;
}

此函数接受两个收入数组 - 添加和更改(因为两个 http 方法), 为它们准备所有承诺(我有批量 POST 但没有 PUT 在我的 API 上)并调用 axios.all 来同时运行它们。现在,乐趣开始了。 当我发布经过 API 验证的正确数据并返回 201 created 时,一切都很好,Promise 解析为当前 axios Response 对象,但是当数据不正确且状态为 400 时,它会解析为未定义。 示例:

axios.all([p1, p2, p3]) // correct data
 -> [<response1>, <response2>, <response3>

axios.all([p1, p2, p3]) // incorrect data
 -> [undefined, undefined, undefined]

它不会抛出错误,它会解析,但无济于事。 但是,浏览器可以正确获取数据(我的意思是,它的状态为 400,但有一个响应主体)。

我不知道该怎么做了,我是 axios 的新手,但它看起来比现在没那么麻烦了。

我的前端应用程序在 React.js 上,它的某些部分仍然使用 fetch API,因为它是一项正在进行的工作。 后端是带有 DRF 的 python Django。

编辑: 此外,我正在使用拦截器,代码如下:

export function setResponseInterceptor({ onSuccess, onError }) {
  if (!onSuccess) {
    onSuccess = response => response;
  }
  axiosInstance.interceptors.response.use(response => {
    if (isHandlerEnabled(response.config)) {
      response = onSuccess(response);
    }
    console.log(response);
    return response;
  }, onError);
}

export function setRequestInterceptor({ beforeSend, onError }) {
  if (!beforeSend) {
    beforeSend = cfg => cfg;
  }
  axiosInstance.interceptors.request.use(cfg => {
    if (isHandlerEnabled(cfg)) {
      cfg = beforeSend(cfg);
    }
    return cfg;
  }, onError);
}
1个回答

Axios axios.all() 上调用 Promise.all() ,以异步方式运行承诺。查看 MDN 对 promises .all 拒绝的定义,你会看到以下内容:

Using Promise.all

Promise.all waits for all fulfillments (or the first rejection).

Rejection

If any of the passed-in promises reject, Promise.all asynchronously rejects with the value of the promise that rejected, whether or not the other promises have resolved.

当你的 API 返回 401 时,它返回失败承诺的拒绝,而忽略其他承诺。

捕获拒绝

使用 .catch ,你将收到一个唯一的承诺拒绝作为参数,并且应该能够读取它的值。

// Using .catch:
Promise.all([p1, p2, p3, p4, p5])
.then(values => { 
  console.log(values);
})
.catch(error => { 
  console.error(error.message)
});

查看你的代码,你需要确保你的函数 saveIncomes 正确处理这种行为。

sebastienbarbier
2019-10-29