我试图用Axios更好地理解javascript承诺。我假装处理request .js中的所有错误,并且只从任何地方调用请求函数,而不必使用catch()。

在本例中,对请求的响应将是400,并带有一个JSON格式的错误消息。

这是我得到的错误:

错误:请求失败,状态码为400

我找到的唯一解决方案是在Somewhere.js中添加.catch(() =>{}),但我试图避免这样做。这可能吗?

代码如下:

Request.js

export function request(method, uri, body, headers) {
  let config = {
    method: method.toLowerCase(),
    url: uri,
    baseURL: API_URL,
    headers: { 'Authorization': 'Bearer ' + getToken() },
    validateStatus: function (status) {
      return status >= 200 && status < 400
    }
  }

  ...

  return axios(config).then(
    function (response) {
      return response.data
    }
  ).catch(
    function (error) {
      console.log('Show error notification!')
      return Promise.reject(error)
    }
  )
}

Somewhere.js

export default class Somewhere extends React.Component {

  ...

  callSomeRequest() {
    request('DELETE', '/some/request').then(
      () => {
        console.log('Request successful!')
      }
    )
  }

  ...

}

当前回答

如果你想要访问整个错误体,请按照下面所示进行:

 async function login(reqBody) {
  try {
    let res = await Axios({
      method: 'post',
      url: 'https://myApi.com/path/to/endpoint',
      data: reqBody
    });

    let data = res.data;
    return data;
  } catch (error) {
    console.log(error.response); // this is the main part. Use the response property from the error object

    return error.response;
  }

}

其他回答

从任何地方调用请求函数,而不必使用catch()。

首先,虽然在一个地方处理大多数错误是一个好主意,但处理请求就不那么容易了。一些错误(例如400个验证错误,如:“用户名已被占用”或“无效的电子邮件”)应该被传递。

所以我们现在使用一个基于Promise的函数:

const baseRequest = async (method: string, url: string, data: ?{}) =>
  new Promise<{ data: any }>((resolve, reject) => {
    const requestConfig: any = {
      method,
      data,
      timeout: 10000,
      url,
      headers: {},
    };

    try {
      const response = await axios(requestConfig);
      // Request Succeeded!
      resolve(response);
    } catch (error) {
      // Request Failed!

      if (error.response) {
        // Request made and server responded
        reject(response);
      } else if (error.request) {
        // The request was made but no response was received
        reject(response);
      } else {
        // Something happened in setting up the request that triggered an Error
        reject(response);
      }
    }
  };

然后可以像这样使用请求

try {
  response = await baseRequest('GET', 'https://myApi.com/path/to/endpoint')
} catch (error) {
  // either handle errors or don't
}

如果你不想使用异步等待尝试

export const post = async ( link,data ) => {
const option = {
    method: 'post',
    url: `${URL}${link}`,
    validateStatus: function (status) {
        return status >= 200 && status < 300; // default
      },
    data
};

try {
    const response = await axios(option);
} catch (error) {
    const { response } = error;
    const { request, ...errorObject } = response; // take everything but 'request'
    console.log(errorObject);
}

如果我理解正确的话,您需要某种全局处理程序,这样就不必为所发出的每个请求附加一个catch处理程序。有一个窗口事件叫做unhandledrejection。

您可以在官方文档中阅读有关此事件的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event

下面是如何为这个事件附加一个监听器:

window.addEventListener('unhandledrejection', (event) => {
  // Handle errors here...
});

如果我理解正确的话,您希望只有在请求成功时才调用请求函数,并且希望忽略错误。为此,您可以创建一个新的承诺,在axios请求成功时解决它,并且在失败时绝不拒绝它。

更新后的代码看起来像这样:

export function request(method, uri, body, headers) {
  let config = {
    method: method.toLowerCase(),
    url: uri,
    baseURL: API_URL,
    headers: { 'Authorization': 'Bearer ' + getToken() },
    validateStatus: function (status) {
      return status >= 200 && status < 400
    }
  }


  return new Promise(function(resolve, reject) {
    axios(config).then(
      function (response) {
        resolve(response.data)
      }
    ).catch(
      function (error) {
        console.log('Show error notification!')
      }
    )
  });

}

如果你想要访问整个错误体,请按照下面所示进行:

 async function login(reqBody) {
  try {
    let res = await Axios({
      method: 'post',
      url: 'https://myApi.com/path/to/endpoint',
      data: reqBody
    });

    let data = res.data;
    return data;
  } catch (error) {
    console.log(error.response); // this is the main part. Use the response property from the error object

    return error.response;
  }

}