文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

我司是怎么封装 Axios 来处理百万级流量中平时少见过的问题

2024-12-03 00:01

关注

本文是我们团队每周分享的内容,该内容是由导师整理分享的。Eaxios 是我们前端团队自己在用的库,由导师封装的,因为其他小伙伴对它有所好奇,所以才有该篇的分享内容。

正文开始~~

Eaxios

Eaxios 是基于 axios 封装的网络请求库,在保持 API 与 axios 基本一致的情况下,简化服务端响应内容和各种异常情况的处理。

开发背景


如上图所示,是一次 Ajax 请求可能输出的结果,在前端我们需要根据输出结果给用户不同的提示。

但是,现有的 Axios 库对于异常结果没有提供较好的封装,Axios Promise catch 里包含各种类型的错误,而且没有提供错误码来识别请求失败的原因。而且很多服务端接口会返回自己的错误码,这样在 Axios Promise then 里也需要处理业务异常。

此外,Axios 本身如下所述的一些问题和局限性。

对于 500 等错误,响应内容会丢失,所以不要去配置 responseType 为 json,对于使用者来说容易采到这个坑。

ps:虽然 Axios 官方文档声明 responseType 是 json,实际上底层调用 XMLHttpRequest 的 responseType 是没有传值的,应该是为了规避这个问题。

ps:应该是为了规避上一个问题,默认提供了一个响应处理函数进行 JSON 解析,但是这会影响性能(500 等响应内容值较多时,会造成页面卡顿)。虽然 transformResponse 可以转换 response,实际接收到的参数是 response.data,所以无法判断具体情况来决定是否进行解析 JSON。

理想情况下,使用者希望 then 返回有效的数据,catch 返回各种错误情况:请求被取消、网络异常、网络超时、服务端异常、服务端数据格式错误、业务异常。

优化方案:

用法说明

eaxios 主要对响应的处理做了一些优化,除了以下部分,eaxios 的 api 与 axios 保持一致:

  1. const eaxios = require('eaxios'); 
  2.  
  3. eaxios.defaults.transformResponse = [ 
  4.   function (data, response) { 
  5.     if (typeof data === 'object') { 
  6.       // 默认约定有成功解析 JSON 对象,就认为服务端成功响应,且有提供错误码 
  7.       if (data.code === 0) { 
  8.         return data.data; 
  9.       } else { 
  10.         throw eaxios.createError(data.message, data.code, response); 
  11.       } 
  12.     } else { 
  13.       // 50x 等服务异常情况 
  14.       throw eaxios.createError( 
  15.         data, 
  16.         response.config.responseError.SERVER_ERROR, 
  17.         response 
  18.       ); 
  19.     } 
  20.   }, 
  21. ]; 
  22.  
  23. return eaxios('https://run.mocky.io/v3/4f503449-0349-467e-a38a-c804956712b7'
  24.   .then((data) => { 
  25.     console.log('success', data.id); 
  26.   }) 
  27.   .catch((error) => { 
  28.     console.log('failure', error.code); // UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和业务错误码 
  29.   }); 

ps:如果存在服务单接口请求规范,可以通过 eaxios.create 创建适用于不同接口规范的请求函数。

  1. interface EaxiosErrorany> extends Error { 
  2.   config: EaxiosRequestConfig; 
  3.   code?: string; 
  4.   request?: any
  5.   response?: EaxiosResponse
  6.   isAxiosError: boolean; 
  7.   toJSON: () => object; 

错误处理函数可以根据错误码 code 来处理异常,code 可能的值为 UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和其他业务错误码。ps:如果要定制错误码,可以在请求配置中添加配置项 `responseError`。

  1. eaxios.defaults.responseError = { 
  2.   REQUEST_OFFLINE: '1'REQUEST_OFFLINE 
  3. }; 

代码示例

下面以 { code: 0, message: 'success', data: { } } 这样的接口规范为例,演示如何使用 eaxios。

  1. const eaxios = require('..'); 
  2.  
  3. const request = eaxios.create({ 
  4.   baseURL: 'https://run.mocky.io/v3'
  5.   timeout: 30000, 
  6.   transformResponse: [ 
  7.     function (data, response) { 
  8.       if (typeof data === 'object') { 
  9.         if (data.code === 0) { 
  10.           return data.data; 
  11.         } else { 
  12.           throw eaxios.createError(data.message, data.code, response); 
  13.         } 
  14.       } else { 
  15.         throw eaxios.createError( 
  16.           data, 
  17.           response.config.responseError.SERVER_ERROR, 
  18.           response, 
  19.         ); 
  20.       } 
  21.     }, 
  22.   ], 
  23. }); 
  24.  
  25. request.interceptors.response.use( 
  26.   function (response) { 
  27.     return response; 
  28.   }, 
  29.   function (error) { 
  30.     if (error && error.code) { 
  31.       if (error.code === 'UNKNOWN') { 
  32.         console.log('未知错误'); 
  33.       } else if (error.code === 'REQUEST_OFFLINE') { 
  34.         console.log('网络未连接'); 
  35.       } else if (error.code === 'REQUEST_TIMEOUT') { 
  36.         console.log('网络有点慢,请求超时了'); 
  37.       } else if (error.code === 'SERVER_ERROR') { 
  38.         console.log('系统出问题了'); 
  39.       } else if (error.code === 'RESPONSE_INVALID') { 
  40.         console.log('服务端 bug'); 
  41.       } else if (error.code === '10000') { 
  42.         // 假设 10000 为登录会话过期 
  43.         console.log('登录会话失效'); 
  44.       } else { 
  45.         console.log('根据情况是否要消息提示,还是外部处理'
  46.       } 
  47.     } 
  48.     throw error; 
  49.   }, 
  50. ); 
  51.  
  52. function printError(error) { 
  53.   console.log( 
  54.     `code: ${error.code}, name: ${error.name}, message: ${error.message}, isAxiosError: ${error.isAxiosError}, stack:\n${error.stack}`, 
  55.   ); 
  56.  
  57. function success() { 
  58.   console.log('>> success'); 
  59.   return request('/4f503449-0349-467e-a38a-c804956712b7'
  60.     .then((data) => { 
  61.       console.log('success', data); 
  62.     }) 
  63.     .catch((error) => { 
  64.       printError(error); 
  65.     }); 
  66.  
  67. function failure() { 
  68.   console.log('>> failure'); 
  69.   return request('/42d7c21d-5ae6-4b52-9c2d-4c3dd221eba4'
  70.     .then((data) => { 
  71.       console.log('success', data); 
  72.     }) 
  73.     .catch((error) => { 
  74.       printError(error); 
  75.     }); 
  76.  
  77. function invalid() { 
  78.   console.log('>> invalid'); 
  79.   return request('/1b23549f-c918-4362-9ac8-35bc275c09f0'
  80.     .then((data) => { 
  81.       console.log('success', data); 
  82.     }) 
  83.     .catch((error) => { 
  84.       printError(error); 
  85.     }); 
  86.  
  87. function server_500() { 
  88.   console.log('>> server_500'); 
  89.   return request('/2a9d8c00-9688-4d36-b2de-2dee5e81f5b3'
  90.     .then((data) => { 
  91.       console.log('success', data); 
  92.     }) 
  93.     .catch((error) => { 
  94.       printError(error); 
  95.     }); 
  96.  
  97. success().then(failure).then(invalid).then(server_500); 
  98.  

兼容性

eaxios 依赖 URLSearchParams 处理表单类型的请求参数,不支持的环境需要引入响应的 polyfill

  1. require("core-js/modules/web.url-search-params.js"

【编辑推荐】

  1. 鸿蒙官方战略合作共建——HarmonyOS技术社区
  2. 云中的容器:你有哪些选择?
  3. 5G消息全力迈入发展期
  4. 什么是域名劫持?遇到域名劫持要怎么处理
  5. 自学编程,到底先选什么语言?
  6. 一文看完网络爬虫发展史

 

来源: 大迁世界内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯