当前位置: 首页 > 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.dtcms.com/a/285629.html

相关文章:

  • 为Notepad++插上JSON格式化的翅膀
  • Git 团队协作完全指南:从基础到高级应用
  • 《向华为学创新》:123页破解华为创新密码【附全文阅读】
  • Jfinal+SQLite解决MYSQL迁移表未复制索引问题,完善迁移工具
  • 私有服务器AI智能体搭建-大模型选择优缺点、扩展性、可开发
  • 数组/链表/【环形数组】实现 队列/栈/双端队列【移动语义应用】【自动扩缩】
  • st-Gcn训练跳绳识别模型六:YOLOv8-Pose 和 ST-GCN 实现实时跳绳计数器应用
  • IDEA 2020.1版本起下载JDK
  • 当OT遇见IT:Apache IoTDB如何用“时序空间一体化“技术破解工业物联网数据孤岛困局?
  • 【每日算法】专题十三_队列 + 宽搜(bfs)
  • 四、CV_GoogLeNet
  • 代码训练营DAY35 第九章 动态规划part03
  • 【收集电脑信息】collect_info.sh
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 基于jieba实现词频统计
  • Kubernetes Pod深度理解
  • 【数据可视化-67】基于pyecharts的航空安全深度剖析:坠毁航班数据集可视化分析
  • 【问题解决】npm包下载速度慢
  • 【AI大模型学习路线】第三阶段之RAG与LangChain——第十八章(基于RAGAS的RAG的评估)RAG中的评估思路?
  • 把握流程节点,明确信息传递
  • C专题5:函数进阶和递归
  • 最小生成树算法详解
  • 2025外卖江湖:巨头争霸,谁主沉浮?
  • 洞见AI时代数据底座的思考——YashanDB亮相2025可信数据库发展大会
  • NIO网络通信基础
  • AndroidX中ComponentActivity与原生 Activity 的区别
  • 关于字符编辑器vi、vim版本的安装过程及其常用命令:
  • 从抓包GitHub Copilot认证请求,认识OAuth 2.0技术
  • web3 区块链技术与用
  • 基于深度学习的语音识别:从音频信号到文本转录
  • 开源的大语言模型(LLM)应用开发平台Dify