当前位置: 首页 > java >正文

微信小程序 wx.request() 的封装

基于微信小程序的wx.request()方法封装

下面是一个封装方案,满足您提出的所有要求:

class HttpService {constructor() {this.baseUrl = ''; // 基础URLthis.pendingRequests = new Map(); // 请求缓存池this.interceptors = {request: [],response: []};}// 设置基础URLsetBaseUrl(url) {this.baseUrl = url;}// 添加拦截器useInterceptor(type, handler) {if (this.interceptors[type]) {this.interceptors[type].push(handler);}}// 核心请求方法async request(config) {const { url, method = 'GET', data = {}, header = {}, showLoading = false } = config;// 生成请求唯一标识const requestKey = `${method}_${url}_${JSON.stringify(data)}`;// 检查重复请求if (this.pendingRequests.has(requestKey)) {return this.pendingRequests.get(requestKey);}// 请求前拦截处理let finalConfig = { url, method, data, header, showLoading };for (const interceptor of this.interceptors.request) {finalConfig = await interceptor(finalConfig) || finalConfig;}// 创建请求Promiseconst requestPromise = new Promise((resolve, reject) => {// 显示加载状态if (finalConfig.showLoading) {wx.showLoading({ title: '加载中', mask: true });}wx.request({url: this.baseUrl + finalConfig.url,method: finalConfig.method,data: finalConfig.data,header: finalConfig.header,success: async (res) => {// 响应后拦截处理let processedRes = res;for (const interceptor of this.interceptors.response) {processedRes = await interceptor(processedRes) || processedRes;}resolve(processedRes);},fail: (err) => {// 错误处理拦截let processedErr = err;for (const interceptor of this.interceptors.response) {processedErr = interceptor(processedErr) || processedErr;}reject(processedErr);},complete: () => {// 隐藏加载状态if (finalConfig.showLoading) {wx.hideLoading();}// 从缓存池移除this.pendingRequests.delete(requestKey);}});});// 缓存当前请求this.pendingRequests.set(requestKey, requestPromise);return requestPromise;}// 并发请求处理all(requests) {return Promise.all(requests);}// 快捷方法:GETget(url, params = {}, config = {}) {return this.request({...config,url,method: 'GET',data: params});}// 快捷方法:POSTpost(url, data = {}, config = {}) {return this.request({...config,url,method: 'POST',data});}// 快捷方法:PUTput(url, data = {}, config = {}) {return this.request({...config,url,method: 'PUT',data});}// 快捷方法:DELETEdelete(url, params = {}, config = {}) {return this.request({...config,url,method: 'DELETE',data: params});}
}// 创建实例
const http = new HttpService();// 设置基础URL(示例)
http.setBaseUrl('https://api.example.com');// 添加请求拦截器(示例:添加token)
http.useInterceptor('request', (config) => {const token = wx.getStorageSync('token');if (token) {config.header = {...config.header,Authorization: `Bearer ${token}`};}return config;
});// 添加响应拦截器(示例:错误处理)
http.useInterceptor('response', (response) => {if (response.statusCode !== 200) {wx.showToast({title: `请求错误: ${response.data.message || '未知错误'}`,icon: 'none'});throw new Error('请求失败');}return response.data;
});

功能说明

  1. 加载状态控制

    • 通过showLoading参数控制是否显示加载动画
    • 默认不显示,需要时手动开启
    • 使用微信原生showLoading/hideLoading方法
  2. 拦截器系统

    • 请求拦截器:在请求发送前修改配置
    • 响应拦截器:处理响应数据和错误
    • 支持添加多个拦截器,按添加顺序执行
  3. 并发请求处理

    • all()方法处理多个并发请求
    • 内部使用Promise.all实现
    • 示例用法:
      const [userData, productList] = await http.all([http.get('/user'),http.get('/products')
      ]);
      

  4. 重复请求过滤

    • 使用请求方法+URL+参数的哈希值作为唯一标识
    • 相同请求返回缓存中的Promise对象
    • 避免网络资源浪费
  5. 快捷方法

    • 内置GET/POST/PUT/DELETE快捷方法
    • 简化常用请求调用
    • 示例:
      // GET请求
      const data = await http.get('/api/data', { page: 1 });// POST请求
      await http.post('/api/submit', { name: 'John' }, { showLoading: true });
      

使用示例

// 获取用户信息
async function fetchUser() {try {const user = await http.get('/user/profile', null, { showLoading: true });console.log('用户数据:', user);} catch (error) {console.error('获取用户信息失败', error);}
}// 提交表单数据
async function submitForm(data) {try {const result = await http.post('/form/submit', data, {showLoading: true,header: { 'Content-Type': 'application/json' }});wx.showToast({ title: '提交成功' });} catch (error) {// 错误已在拦截器处理}
}// 并发请求示例
async function fetchAllData() {try {const [orders, messages] = await http.all([http.get('/user/orders'),http.get('/user/messages')]);console.log('订单数据:', orders);console.log('消息数据:', messages);} catch (error) {console.error('数据获取失败', error);}
}

这个封装方案具有以下优势:

  1. 完整的拦截器系统支持预处理和后处理
  2. 智能的请求缓存机制避免重复请求
  3. 简洁的API设计降低使用复杂度
  4. 完善的错误处理流程
  5. 灵活的加载状态控制
  6. TypeScript友好,可轻松添加类型定义
http://www.xdnf.cn/news/15671.html

相关文章:

  • Github库镜像到本地私有Gitlab服务器
  • PortSwigger Labs 之 点击劫持利用
  • RPC 与 Feign 的区别笔记
  • Spring AI开发智能客服(Tool calling)
  • 开启modbus tcp模拟调试
  • 【LeetCode 热题 100】199. 二叉树的右视图——(解法一)BFS
  • 自己动手实现 strlen:从循环到递归的四种写法
  • Postman/Apipost中使用Post URL编码发送含换行符参数的问题分析
  • 现代R语言机器学习:Tidymodel/Tidyverse语法+回归/树模型/集成学习/SVM/深度学习/降维/聚类分类与科研绘图可视化
  • 串口(Serial Port)是什么?
  • 在 React 中根据数值动态设置 SVG 线条粗细
  • 【52】MFC入门到精通——MFC串口助手(二)---通信版(发送数据 、发送文件、数据转换、清空发送区、打开/关闭文件),附源码
  • 9. isaacsim4.2教程-ROS加相机/CLOCK
  • vs openssl编译提示无法打开文件“libssl.lib”或“libcrypto.lib”
  • 回归预测 | MATLAB实现SA-BP模拟退火算法优化BP神经网络多输入单输出回归预测
  • 搜广推校招面经九十五
  • stm32驱动双步进电机
  • Linux入门篇学习——借助 U 盘或 TF 卡拷贝程序到开发板上
  • UniApp -- 小程序自定义导航栏组件
  • 论文征集 | 国产工业软件硕博学位论文激励计划启动
  • 主流编程语言全景图:从Python到Rust的深度解析
  • 网络基础12--可靠性概述及要求
  • sky-take-out项目Mybatis的使用
  • 高性能数据库-Redis详解
  • 网关-微服务网关入门
  • STM32-第七节-TIM定时器-3(输入捕获)
  • 深度解析Linux文件I/O三级缓冲体系:用户缓冲区→标准I/O→内核页缓存
  • 如何在服务器上获取Linux目录大小
  • Mysql数据库——增删改查CRUD
  • *SFT深度实践指南:从数据构建到模型部署的全流程解析