关于对小程序网络请求的封装(详尽版)
引导读者从最基础的小程序网络请求封装到网络请求封装的最优解
在使用原生小程序网络api时,有以下两个缺点:
- 多个页面往往代表发送多个网络请求,这样对服务器的压力过大 -> 降压
- 基于原因1,防止未来微信官方废弃了wx.request这个api而换了另外一个api时造成的重复操作 ->降低依赖,防止重复
1. wx原生网络请求
微信原生请求看似很清晰,但成功与失败的函数都是在 wx.request内部,假设读者对jQuery有所了解,就会发觉跟jquery很像:
但这种方法已经濒临灭绝了,接下来使用基于promise对微信原生网络请求进行层层封装
2. 简单封装
// ../../request/one.js export default function reqeust(params) { return new Promise((resolve, reject) => { wx.request({ url: params.url, method: params.method || 'get', data: params.data || {}, success: res => { resolve(res) }, fail: err => { reject(err) } }) }) }
如果对pomise相当了解,也可以使用进化版:
// ../../request/one.js export default function reqeust(params) { return new Promise((resolve, reject) => { wx.request({ url: params.url, method: params.method || 'get', data: params.data || {}, success: resolve, fail: reject }) }) }
页面内使用:
//页面内导入 import reqeust from '../../request/one.js' // 页面的onload函数内使用 onLoad: function () { reqeust({ url: 'https://xxxxxxxxxxxxxxxxxxxxxxxxxxx', }) .then(res => { console.log(res) }) .catch(err => console.log(err)) }
结果也是一样的
3. 进化版封装
回顾下es6的导入导出知识:
// 常量的导出 //public.js const demo = '使用export导出的常量,不可以重命名该常量,需要用大括号'; export { demo } //常量的导入 //getdemo.js import { demo } from './public' console.log(demo ) // '使用export导出的常量,不可以重命名该常量,需要用大括号' //函数的导出与导入 //函数的导出 //fn.js export function fn() { console.log("使用export导出的fn,不可以重命名该函数,需要用大括号") } //函数的导入 //getFn.js import { fn } from './fn.js' fn(); // "使用export导出的fn,不可以重命名该函数,需要用大括号" //全部导出与导入 //导出 //allData.js export default function allData() { console.log("使用export default 导出的数据,可以重命名该函数,不需要用大括号") } //getAllData.js //导入 import reName_AllData from './allData.js' reName_AllData()//"使用export default 导出的数据,可以重命名该函数,不需要用大括号"
假设请求的url有一部分是相同的
- 将url分为两部分:第一部分作为公共的请求地址publicURL,单独抽离成一个文件,另一部分作为单个页面请求的网络地址PageUrl
- 在requers.js里将公共的请求地址publicURL添加进url里
- 页面导入request.js 发起请求
//抽取公共url到单独文件 //publicData.js const baseURL = 'https://jiazhuang/zheshi/yige/gonggongurl'; export { baseURL } //封装的网络请求文件,导入上述文件 //network1-0.js import { baseURL } from './public' export function request(params) { return new Promise((resolve, reject) => { wx.request({ url: baseURL + params.url, method: params.method || 'get', data: params.data || {}, success: resolve, fail: reject }); }) } //页面使用时仅填入对应的网络地址即可 //页面导入封装好的network1-0.js import { request } from '../../req/newwork1-5' //onLoad函数内使用 onLoad: function () { request({ url: 'public/v1/home/swiperdata' }).then(res => { console.log(res) }) .catch(err => console.log(err)) }
以上就是第二层封装.
但是这样还是有不太方便的一面:
单个页面需要发送的请求太多,代码的可读性并不太好
那么就有了终极版封装:
4. 网络请求的究极封装
这一步时,我们的目的就是为了分层:
基于页面分层,封装单个页面需要发送的请求为一个文件getPage.js由page.js负责向request.js发送真正的网络请求,而页面要做的就是调用page.js里的单个请求方法
以下为图示:
解释:
- request.js负责将公共api与getPage.js里传入的api进行拼接,整合后向后台发送数据
- getPage.js向上负责向request.js发送请求,向下作为发送请求函数等待被调用,函数内部存储非公共api
- page作为页面,仅调用getPage.js内部的函数即可
整演示例
//publicData.js 作为api的公共部分 const baseUrl= 'https://jiazhuang-shiyige-api/api/'; export { baseUrl } //request.js 作为真正发送网络请求的文件 import { publicUrl } from './publicData' export default function reqeust(params) { return new Promise((resolve, reject) => { wx.request({ url: publicUrl + params.url, method: params.method || 'get', data: params.data || {}, success: resolve, fail: reject }) }) } // getIndexData.js : 向上负责调用request.js,向下负责该page页面的发送网络请求的所有函数,函数的内部存储了非公共部分的请求地址 import reqeust from './request' export function getBannerData() { return reqeust({ url: 'wo/zhen-de/shi/api/banner', }) } //index页面导入所属的getIndexData.js,在onload函数内调用所属页面的方法 import { getBannerData} from '../../request/getIndexData' onload(){ getBannerData().then(res => { console.log(res) //这里就可以对数据进行操作了 }).catch(err => console.log(err)) }
在这个例子里,一步步解释了流程,或许有些冗余,但这些更符合了规范化,page页面不关心发送网络请求,只负责调用,getPageData.js只负责将对应的url发送给request.js处理,而request.js负责拼接整合url以及其他,最终发送向网络请求.如果愿意,还可以单个页面再细分,所作的一切都是为了服务于开发.
以上就是将小程序的原生网络请求一步步封装达到最优解.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了