# 微信小程序 wx.request 高级封装 **Repository Path**: LongRunGood/wxRequestEncapsulation ## Basic Information - **Project Name**: 微信小程序 wx.request 高级封装 - **Description**: 微信小程序 wx.request 高级封装 - **Primary Language**: 微信 - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-05-07 - **Last Updated**: 2024-05-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 微信小程序 wx.request 高级封装 ## 介绍 wx.request 高级封装 ## 软件架构 - pages(页面) - index(首页) - req(api接口) - api(接口) - index.js(接口配置) - utils(封装代码) - request.js(wx.request 封装) - util.js(公用函数封装) - .gitignore(git提交忽略文件) - LICENSE(开源协议) - README.md(介绍) - app.js(全局js) - app.json(全局配置) - app.wxss(全局样式) - project.config.json (项目配置文件) - sitemap.json(sitemap配置) ## 开发思路 #### 并发处理 研究封装wx.request,发现wx.request在1.4.0版本以上同时请求数量最多为10个,多余的请求会排队处理,而1.4.0及以下版本,wx.request同时请求数量最多为5个,多余的请求会报错,所以需要做并发的兼容处理。 #### Promise 使用promise链式来代替回调函数。 ``` /** * promise请求 * 参数:参考wx.request * 返回值:[promise]res */ function requestP(options = {}) { const { success, fail, } = options; return new Promise((res, rej) => { wx.request(Object.assign( {}, options, { success: res, fail: rej, }, )); }); } ``` #### 精简返回值 当请求返回并丢给一大堆数据时,直接取想要的那一部分数据就好。 ``` return new Promise((res, rej) => { wx.request(Object.assign( {}, options, { success(r) { res(r.data); // 这里只取data }, fail: rej, }, )); }); ``` 但是需要注意,仅仅取data部分,这时候默认所有success都是成功的,其实不然,wx.request是一个基础的api,fail只发生在系统和网络层面的失败情况,比如网络丢包、域名解析失败等等,而类似404、500之类的接口状态,依旧是调用success,并体现在statusCode上。 从业务上讲,我只想处理json的内容,并对json当中的相关状态进行处理;如果一个接口返回的不是约定好的json,而是类似404、500之类的接口异常,我统一当成接口/网络错误来处理,就像jquery的ajax那样。 也就是说,如果我不对statusCode进行区分,那么包括404、500在内的所有请求结果都会走requestP().then,而不是requestP().catch。 ``` /** * 判断请求状态是否成功 * 参数:http状态码 * 返回值:[Boolen] */ function isHttpSuccess(status) { return status >= 200 && status < 300 || status === 304; } ``` isHttpSuccess用来决定一个http状态码是否判为成功,于是结合requestP,可以这么来用: ``` return new Promise((res, rej) => { wx.request(Object.assign( {}, options, { success(r) { const isSuccess = isHttpSuccess(r.statusCode); if (isSuccess) { // 成功的请求状态 res(r.data); } else { rej({ msg: `网络错误:${r.statusCode}`, detail: r }); } }, fail: rej, }, )); }); ``` #### 登录&sessionId 判断是否要登录验证和通过header的方式来携带sessionId,以及登录过期自动登录。 ## 参考资料 #### 研究公司已封装好的request代码 1. 对低版本请求并发进行了处理。 2. 独立封装了登录逻辑。(大致思路是主动轮询续期) #### mp-req (GitHub: https://github.com/wxlite-plus/mp-req) 1. 简化respone:简化返回的数据信息,只保留业务数据; 2. method替代url:使用js api的书写方式来替代直接书写url的方式; 3. 自动登录:登录态过期自动重新登录,过程对开发者透明。(大致思路是被动按需续期) 4. promisify:支持promise,替代callback的方式 ** 但是没有做低版本的请求并发兼容。 ** ## 项目日志 #### 2019.12.17 根据公司封装代码和mp-req的各自优点,将两者结合下,再封装一个request。(大体是mp-req,但要加对低版本的并发兼容) #### 2019.12.18 request封装基本完成,登录逻辑可以在优化下。 ## 我的博客 [wx.request 高级封装](https://blog.csdn.net/tianyu0_0/article/details/103600229) ## 感谢 #### 以下是我到网上查找的一些文章,对本人有较大启发,在此十分感谢! 1. 一个通用request的封装 (链接: https://developers.weixin.qq.com/community/develop/article/doc/000cac14f44e70059368f3c1b5bc13) 2. mp-req (链接: https://github.com/wxlite-plus/mp-req) ## 责任声明 仅供学习参考,请勿用于商业,如有问题,概不负责。