事件通过

这是一个工作中发现的问题,简略形容一下场景:后端 api 接口返回格局大抵如下:

{  code: 200, // 200 示意接口返回失常,非 200 则为异样  data: {}, // 返回的数据  message: '', // 接口报错时的错误信息}
  • 当 code 字段为 200 时,则示意接口失常,这时候咱们失常取数据就行;
  • 当 code 为非 200 时,示意接口异样,此时咱们须要把对应的错误信息进行弹窗报错;

这属于一个通用的解决,因而咱们能够利用 axios 返回拦截器进行解决:

import axios from 'axios';const handleRes = config => {  if (config.data.code !== 200) {    throw config;  }  return config;};const handleErr = error => {  // 把错误信息进行弹窗};axios.interceptors.response.use(handleRes, handleErr);

=.= 这就是我的直觉写法,handleRes 函数对响应体进行解决,对返回数据的 code 进行判断,如果不为 200 则抛出一个谬误,并由 handleErr 函数捕捉,而后再进行弹窗解决。

究竟还是出问题了

想法很美妙,但其实 handleErr 是不失效的……

贴个官网的示例:

// Add a response interceptoraxios.interceptors.response.use(function (response) {  // Any status code that lie within the range of 2xx cause this function to trigger  // Do something with response data  return response;}, function (error) {  // Any status codes that falls outside the range of 2xx cause this function to trigger  // Do something with response error  return Promise.reject(error);});
只有状态码超过 2xx 便会触发这个函数

也就是说,它只会在申请异样时触发,也就是接口 http code 不为 2xx 时。

发现起因

解决问题,首先要钻研源码 =.=

const responseInterceptorChain = [];this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {  responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);});// ...省略一大段代码try {  promise = dispatchRequest.call(this, newConfig);} catch (error) {  return Promise.reject(error);}i = 0;len = responseInterceptorChain.length;while (i < len) {  promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);}

能够看出拦截器中的参数最终会作为 Promise.prototype.then 的参数,也就是说咱们的代码能够等同于:

promise.then(handleRes, handleErr);

而 handleErr 函数只捕捉 promise 变量的谬误,不捕捉 handleRes 函数中的谬误,如果须要捕捉,应该在前面应用 catch 或是 then 函数:

promise.then(handleRes, handleErr).catch(err => {});promise.then(handleRes, handleErr).then(undefined, err => {});

换成拦截器的语法,也就是再新增一个响应拦截器,定义一个谬误捕捉函数:

import axios from 'axios';const handleRes = config => {  if (config.data.code !== 200) {    throw config;  }  return config;};const handleErr = error => {  // 把错误信息进行弹窗};axios.interceptors.response.use(handleRes);axios.interceptors.response.use(undefined, handleErr);

后续

谢谢观看,心愿能够帮到你!