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

微信小程序 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.lryc.cn/news/592375.html

相关文章:

  • 【图像处理基石】什么是CCM?
  • 解决 Selenium 页面跳转过快导致的内容获取问题:从原理到实践
  • 填坑 | React Context原理
  • 29、鸿蒙Harmony Next开发:深浅色适配和应用主题换肤
  • 私有服务器AI智能体搭建配置选择记录
  • 苍穹外卖项目日记(day12)
  • 再探Java多线程Ⅱ --- (创建方式+等待唤醒+Lock锁)
  • 【论文蒸馏】Recent Advances in Speech Language Models: A Survey
  • 《设计模式之禅》笔记摘录 - 8.命令模式
  • 企业如何让内部视频仅限公司官网或指定域名播放?
  • 2025年SEVC SCI2区,利用增强粒子群算法(MR-MPSO)优化MapReduce效率和降低复杂性,深度解析+性能实测
  • 某邮生活旋转验证码逆向
  • 5W8-3D牢游戏超级大集合[2012年6月] 地址 + 解压密码
  • Python绘制数据(二)
  • C语言实战:超级玛丽游戏
  • 工业数据集成中间件工具OPC Router详细介绍
  • 大模型格式
  • sky-take-out项目Mybatis的使用
  • AE电源MDX 5K 10K 15K 20K 25K 30K手侧操作使用说明
  • 【Linux】环境基础与开发工具的使用
  • 数据结构--JDK17新增语法和顺序表
  • blender如何队列渲染多个工程文件的动画?
  • 集训Demo4
  • 本地部署 Kimi K2 全指南(llama.cpp、vLLM、Docker 三法)
  • 【playwright篇】教程(十六)[macOS+playwright相关问题]
  • ClickHouse物化视图避坑指南:原理、数据迁移与优化
  • IntelliJ IDEA大括号格式设置:换行改行尾
  • C#测试调用ServiceController类查询及操作服务的基本用法
  • vscode编辑Markdown文件
  • 【51】MFC入门到精通——MFC串口助手(一)---初级版(串口设置、初始化、打开/关闭、状态显示),附源码