微信小程序网络请求进阶:从基础封装到实战优化

张开发
2026/4/12 16:02:20 15 分钟阅读

分享文章

微信小程序网络请求进阶:从基础封装到实战优化
1. 为什么需要封装wx.request微信小程序的网络请求API wx.request 是一个基础的异步接口使用回调函数的方式处理响应结果。在实际开发中直接使用原生API会遇到几个典型问题首先是回调地狱问题。当需要连续发起多个请求时代码会形成多层嵌套比如获取用户信息后再获取订单列表代码会变成这样wx.request({ url: user/info, success: (userRes) { wx.request({ url: order/list, data: {userId: userRes.id}, success: (orderRes) { // 更多嵌套... } }) } })其次是重复代码问题。每个请求都需要处理错误情况、设置基础URL、添加公共header等这些重复代码会让项目难以维护。我在实际项目中就遇到过这样的困扰当需要统一修改超时时间或添加新的公共参数时需要在几十个地方逐个修改不仅效率低下还容易遗漏。2. Promise化基础封装2.1 创建Request类使用ES6的Class来封装可以更好地组织代码。我们先创建一个WxRequest类class WxRequest { constructor() { this.defaults { baseURL: , timeout: 60000, header: { Content-Type: application/json } } } request(options) { return new Promise((resolve, reject) { wx.request({ ...options, success: (res) resolve(res), fail: (err) reject(err) }) }) } }这个基础版本已经解决了回调地狱问题现在可以这样使用const instance new WxRequest() const res await instance.request({url: /api/data})2.2 合并请求参数实际开发中我们需要合并三类参数类中定义的默认参数实例化时传入的参数调用request方法时传入的参数修改constructor和request方法constructor(params {}) { this.defaults Object.assign({}, this.defaults, params) } request(options) { options { ...this.defaults, ...options, url: this.defaults.baseURL options.url } // 剩余代码不变 }3. 实现快捷方法3.1 添加GET/POST等方法模仿axios的API设计我们可以添加常用的HTTP方法class WxRequest { // ...其他代码 get(url, data {}, config {}) { return this.request({ url, data, method: GET, ...config }) } post(url, data {}, config {}) { return this.request({ url, data, method: POST, ...config }) } // 类似添加put/delete等方法 }现在调用变得更简洁// 之前 instance.request({url: /api, method: GET}) // 现在 instance.get(/api)4. 拦截器实现4.1 请求拦截器请求拦截器可以在发送请求前统一处理参数比如添加tokenclass WxRequest { constructor() { this.interceptors { request: null, response: null } } request(options) { // 请求拦截 if (this.interceptors.request) { options this.interceptors.request(options) } // 剩余代码不变 } } // 使用示例 instance.interceptors.request (config) { const token wx.getStorageSync(token) if (token) { config.header config.header || {} config.header[Authorization] token } return config }4.2 响应拦截器响应拦截器可以统一处理响应数据和错误request(options) { return new Promise((resolve, reject) { wx.request({ ...options, success: (res) { const mergedRes {...res, config: options} resolve(this.interceptors.response?.(mergedRes) ?? mergedRes) }, fail: (err) { const mergedErr {...err, config: options} reject(this.interceptors.response?.(mergedErr) ?? mergedErr) } }) }) } // 使用示例 instance.interceptors.response (response) { if (response.statusCode ! 200) { wx.showToast({title: 请求失败, icon: error}) return Promise.reject(response) } return response.data }5. 高级功能实现5.1 并发请求处理使用Promise.all实现并发请求class WxRequest { all(promises) { return Promise.all(promises) } } // 使用示例 const [userRes, orderRes] await instance.all([ instance.get(/user), instance.get(/orders) ])5.2 文件上传封装封装wx.uploadFile方法class WxRequest { upload(url, filePath, name, config {}) { return new Promise((resolve, reject) { wx.uploadFile({ url: this.defaults.baseURL url, filePath, name, ...config, success: (res) { try { res.data JSON.parse(res.data) resolve(res) } catch (e) { reject(e) } }, fail: reject }) }) } }6. 性能优化实践6.1 请求队列管理为了避免频繁显示/隐藏loading我们需要管理请求队列class WxRequest { constructor() { this.queue [] } request(options) { // 显示loading if (options.isLoading ! false this.queue.length 0) { wx.showLoading() } this.queue.push(request) return new Promise((resolve, reject) { wx.request({ ...options, complete: () { this.queue.pop() if (this.queue.length 0) { wx.hideLoading() } } // 其他回调不变 }) }) } }6.2 环境变量配置根据小程序环境切换不同baseURLconst env wx.getAccountInfoSync().miniProgram.envVersion const configs { develop: {baseURL: https://dev.example.com}, trial: {baseURL: https://test.example.com}, release: {baseURL: https://api.example.com} } const instance new WxRequest(configs[env] || configs.release)7. 完整代码结构建议一个完整的网络请求模块可以这样组织utils/ request.js # 核心封装 env.js # 环境配置 api/ user.js # 用户相关接口 order.js # 订单相关接口user.js示例import http from ../utils/request export const login (data) http.post(/user/login, data) export const getUserInfo () http.get(/user/info)在页面中使用import { getUserInfo } from ../../api/user Page({ async onLoad() { const userInfo await getUserInfo() // 处理数据 } })这种架构的好处是接口统一管理便于维护业务组件只需关注数据使用不关心请求细节修改接口时只需调整对应模块在实际项目中这种封装方式可以使网络请求代码量减少40%以上同时大大提高可维护性。特别是在需要修改公共参数或处理方式时只需修改一处即可全局生效。

更多文章