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

2023-01-22 0 378

责任编辑是他们项目组每星期撷取的文本,该文本是由指导老师重新整理撷取的。Eaxios 是他们后端项目组他们在用的库,由指导老师PCB的,即使其它爸爸妈妈对它略有疑惑,因此才有该篇的撷取文本。

节录已经开始~~

Eaxios

Eaxios 是如前所述 axios PCB的互联网允诺库,在维持 API 与 axios 大致相同的情形下,精简伺服器端积极响应文本和各式各样极度情形的处置。

合作开发大背景

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

示意图右图,是一场 Ajax 允诺可能将输入的结论,在后端他们须要依照输入结论给使用者相同的提示信息。

允诺被中止:忽视互联网极度:提示信息检查和与否相连互联网允诺延时:提示信息互联网慢,请转换互联网伺服器极度:提示信息控制系统出难题了积极响应导出失利:上列,且能展开严重错误笔记呈报允诺失利:此种情形一般来说是销售业务极度,后端须要依照万萨县展开适当的处置,最简单的是最新消息告诫允诺获得成功:后端领到统计数据后更狸尾豆

但,原有的 Axios 库对极度结论没提供更多良好的PCB,Axios Promise catch 里包涵多种类型的严重错误,因此没提供更多万萨县来辨识允诺失利的其原因。因此许多伺服器端USB会回到他们的万萨县,这种在 Axios Promise then 里也须要处置销售业务极度。

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

如果设置 Axios responseType 为 json 时,伺服器端回到的非 JSON 格式的积极响应文本会即使无法导出,response.data 为 null对 500 等严重错误,积极响应文本会丢失,因此不要去配置 responseType 为 json,对使用者来说容易采到这个坑。ps:虽然 Axios 官方文档声明 responseType 是 json,实际上底层调用 XMLHttpRequest 的 responseType 是没传值的,应该是为了规避这个难题。Axios 默认不管 HTTP 积极响应状态和 responseType 是什么,都会调用默认的 transformResponseps:应该是为了规避上一个难题,默认提供更多了一个积极响应处置函数展开 JSON 导出,但这会影响性能(500 等积极响应文本值较多时,会造成页面卡顿)。虽然 transformResponse 能转换 response,实际接收到的参数是 response.data,因此无法判断具体情形来决定与否展开导出 JSON。Axios then 和 catch 是依照 validateStatus 决定的,使用者处置以来较为麻烦。理想情形下,使用者希望 then 回到有效的统计数据,catch 回到各式各样严重错误情形:允诺被中止、互联网极度、互联网延时、伺服器端极度、伺服器端统计数据格式严重错误、销售业务极度。Axios 默认不处置content-typeapplication/x-www-form-urlencoded 类型的允诺体,使用起来不够方便

优化方案:

如果设置 Axios responseType 为 json 时,不要传给传 XMLHttpRequest,以避免非 JSON 格式的积极响应文本丢失Axios 依照积极响应头的 content-type 判断与否须要导出 JSON,以避免性能难题通过允诺拦截器实现不给 Axios 传递 transformResponse 配置,且将配置备份到其它字段上,然后在积极响应拦截器中将积极响应对象 response 传递给 transformResponse 处置。响应拦截器依照 response 提供更多的状态码、积极响应头和积极响应文本判断与否要展开 JSON 转换。中止 Axios validateStatus 的配置选项,默认所有大于 0 的状态码都是正确的状态码,然后在 Axios 拦截器 then 中展开统计数据导出(非 200 的可能将也是 JSON,因此要复用 200 的 JSON 导出代码),并且依照极度情形抛出直观的严重错误对象内置默认处置表单类型的允诺体

用法说明

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

eaxios 允诺配置的 transformResponse 传参和处置时机发生了变化axios 在伺服器端积极响应文本后就会调用 transformResponse 展开积极响应转换,eaxios 积极响应后内部自动依照积极响应头和 responseType 展开 JSON 导出,然后将导出后的统计数据和 response 传给 transformResponse,transformResponse 回到的统计数据最终会被 Promise resovle 给外部调用者。假设伺服器端回到的统计数据结构为{ code: 0, message: success, data: {} },code 为 0 表示正确的积极响应,非 0 表示极度,USB允诺的代码示例如下右图:const eaxios = require(eaxios); eaxios.defaults.transformResponse = [ function (data, response) { if (typeof data === object) { // 默认约定有获得成功导出 JSON 对象,就认为伺服器端获得成功积极响应,且有提供更多万萨县 if (data.code === 0) { return data.data; } else { throweaxios.createError(data.message, data.code, response); } } else { // 50x 等服务极度情形 throweaxios.createError(data, response.config.responseError.SERVER_ERROR, response ); } }, ]; return eaxios(https://run.mocky.io/v3/4f503449-0349-467e-a38a-c804956712b7) .then((data) => { console.log(success, data.id); }) .catch((error) => { console.log(failure, error.code); // UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和销售业务万萨县 }); ps:如果存在服务单USB允诺规范,能通过 eaxios.create 创建适用于相同USB规范的允诺函数。 eaxios 的允诺处置函数 then 只会接收到 transformResponse 转换后的统计数据,对互联网、延时、伺服器端极度和销售业务极度等难题,会在 catch 接收一个 EaxiosError 类型的严重错误对象。interface EaxiosError<T = any> extendsError { config: EaxiosRequestConfig; code?:string; request?: any; response?: EaxiosResponse<T>; isAxiosError: boolean; toJSON: () =>object; } 严重错误处置函数能依照万萨县 code 来处置极度,code 可能将的值为 UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和其它销售业务万萨县。 ps:如果要定制万萨县,能在允诺配置中添加配置项`responseError`。 eaxios.defaults.responseError = { REQUEST_OFFLINE: 1REQUEST_OFFLINE }; eaxios 内部会自动序列化表单类型的允诺参数,因此主要传对象给 data 就行了。

代码示例

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

const eaxios = require(..); const request = eaxios.create({ baseURL: https://run.mocky.io/v3, timeout: 30000,transformResponse: [ function (data, response) { if (typeof data === object) { if (data.code === 0) { returndata.data; }else { throw eaxios.createError(data.message, data.code, response); } } else { throweaxios.createError( data, response.config.responseError.SERVER_ERROR, response, ); } }, ], }); request.interceptors.response.use(function (response) { returnresponse; },function (error) { if (error && error.code) { if (error.code === UNKNOWN) { console.log(未知严重错误); } else if (error.code === REQUEST_OFFLINE) { console.log(互联网未相连); } else if (error.code === REQUEST_TIMEOUT) {console.log(互联网有点慢,允诺延时了); } else if (error.code === SERVER_ERROR) { console.log(控制系统出难题了); } else if (error.code === RESPONSE_INVALID) { console.log(伺服器端 bug); } else if (error.code === 10000) { // 假设 10000 为登录会话过期 console.log(登录会话失效); } else { console.log(依照情形与否要最新消息提示信息,还是外部处置) } } throwerror; }, );function printError(error) { console.log( `code: ${error.code}, name: ${error.name}, message: ${error.message}, isAxiosError: ${error.isAxiosError}, stack:\n${error.stack}`, ); } function success() { console.log(>> success); return request(/4f503449-0349-467e-a38a-c804956712b7) .then((data) => { console.log(success, data); }) .catch((error) => { printError(error); }); } function failure() { console.log(>> failure); return request(/42d7c21d-5ae6-4b52-9c2d-4c3dd221eba4) .then((data) => { console.log(success, data); }) .catch((error) =>{ printError(error); }); }function invalid() { console.log(>> invalid); return request(/1b23549f-c918-4362-9ac8-35bc275c09f0) .then((data) => { console.log(success, data); }) .catch((error) =>{ printError(error); }); }function server_500() { console.log(>> server_500); return request(/2a9d8c00-9688-4d36-b2de-2dee5e81f5b3) .then((data) => { console.log(success, data); }) .catch((error) =>{ printError(error); }); } success().then(failure).then(invalid).then(server_500);/* log >> success success { id: 1 } >> failure 登录会话失效 code: 10000, name: Error, message: error, isAxiosError: true, stack: … >> invalid 伺服器端 bug code: RESPONSE_INVALID, name: SyntaxError, message: Unexpected token V in JSON at position 0, isAxiosError: true, stack: … >> server_500 控制系统出难题了 code: SERVER_ERROR, name: Error, message: …, stack: … */

兼容性

eaxios 依赖 URLSearchParams 处置表单类型的允诺参数,不支持的环境须要引入积极响应的 polyfill

core-jsrequire(“core-js/modules/web.url-search-params.js”) url-search-params-polyfill

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务