找回密码
 立即注册

QQ登录

只需一步,快速开始

[工具插件] 微信小程序 请求 封装, promise, 请求并发限制, 排队请求, ...

[复制链接]
查看: 394|回复: 7
最佳答案
0 

6

主题

6

帖子

140

积分

新人求带

积分
140
 楼主| 发表于 2019-9-19 15:06:15 | 显示全部楼层 |阅读模式
微信小程序请求封装

为什么要封装

主要是为了更加严苛的控制请求数, 以及使用async 来控制请求, 要求请求对象是 promise对象, 但目前使用的尽管是promise对象, 抛弃请求却十分的不方便 有的时候需要离开详情页, 详情页的请求也希望全部抛弃, 因此自己封装了

优势

promise
并发限制: 动态排队请求, 超过配置的请求, 将排成队列, 等待最大完成请求数, 依次补上, 不等待空闲时间, 避免请求失败
保留主动抛弃请求
可配置
分离 请求前后的业务逻辑, 参考 koa2 的洋葱模型


demo
  1.     /**
  2.      *  网络请求
  3.      *
  4.      * @param {string}  url 请求url
  5.      * @param {object}  data 表单内容
  6.      *
  7.      * @param {object}  options 扩展属性
  8.      * @param {boolean} options.baseUrl
  9.      * @param {string}  [options.methods='POST'] methods
  10.      * @param {string}  [options.header={...}] methods
  11.      * @param {boolean} [options.dataType=json] dataType
  12.      * @param {boolean} [options.noBaseUrl=false] 本地扩展
  13.      */
  14.     let request = requeir('./src/index');

  15.         request.get('/system/getConfig.do', {time: 1}, {});
  16.         request.put('/system/getConfig.do', {time: 1}, {});
  17.         request.post('/system/getConfig.do', {time: 1}, {});

  18.             // 直接抛弃请求
  19.         request('/system/getConfig.do', {time: 1}, {}).abort();
  20.         
  21.         // 发送出去后抛弃请求
  22.         let request1 = request('/system/getConfig.do', {time: 2}, {});
  23.         setTimeout(() => {
  24.             request1.abort();
  25.         }, 30);

  26.         request('/system/getConfig.do', {time: 3}, {});
  27.         request('/system/getConfig.do', {time: 4}, {});
  28.         request('/system/getConfig.do', {time: 5}, {noToken: true});

  29.         // 队列中被直接抛弃
  30.         let request2 = request('/system/getConfig.do', {time: 6}, {});
  31.         setTimeout(() => {
  32.             request2.abort();
  33.         }, 30);

  34.         request('/system/getConfig.do', {time: 7}, {});
  35.         request('/system/getConfig.do', {time: 8}, {}).then(()=> {
  36.             
  37.         });
复制代码
配置
config.js
通用配置

  1.     exports.config = {
  2.         baseUrl: 'https://baidu.com', // 统一请求基路径
  3.         header: {
  4.             'content-type': 'application/x-www-form-urlencoded'
  5.         }, // header
  6.         dataType: 'json',
  7.         maxLink: 8, // 最大 并发请求
  8.         response: {
  9.             abort: {errMsg: 'request:fail abort'} // 取消请求后的回调消息
  10.         }
  11.     };
复制代码

拦截器 (学习koa2)
拦截器的目的是为了分离 业务代码 与 请求体 我们常见的是 比如 带 token, 我们可能会写在 请求里面,
  1.     // 请求前
  2.     data.token = app.token;

  3.     // 或者在请求成功后
  4.     success: (res) {
  5.         let {data} = res;
  6.         
  7.         if (data.code !== 0) {
  8.             return Promise.reject('请求失败')
  9.         }
  10.         if (data.code === 103) {
  11.             return // 跳转到 登录页面
  12.         }
  13.         // if ().....
  14.     }
复制代码

注入此类, 为此, 在请求 模仿 类似 koa2一样的洋葱模型, 增加了拦截器 interceptors.request[] 传入多个 方法或Promise, 请求前的ctx包含了{url, data, options} 请求后的ctx, 为 小程序请求回来的对象
  1.    exports.interceptors = {

  2.         /**
  3.         * 请求之前
  4.         * @param {boolean} [ctx.options.noToken=false] 扩展
  5.         */
  6.         request: [
  7.             async (ctx) => {
  8.                 let {options} = ctx;
  9.                 if (!app.token) {
  10.                     return Promise.reject(666);
  11.                 }
  12.             },
  13.             // ...async(ctx)=> {}
  14.         ],

  15.         // 请求成功的拦截器, (请求失败的拦截器没有对外开方)
  16.         response: [
  17.             async (ctx) => {
  18.                 return ctx.data; // 表示只需要 原来的小程序 data内的对象
  19.             },
  20.             async (ctx) => {
  21.                 if (ctx.code !== 0) {
  22.                     return Promise.reject(ctx); // 进入这里, 那么请求将会以 reject 的方式回调
  23.                 }
  24.             }
  25.         ]
  26.     };
复制代码
更多的设置

在 src/index中 配置了一些基本的拦截器
  1.     // 用于初始化数据
  2.     async(ctx) => {
  3.         ctx.options = {
  4.             baseUrl: ctx.options.baseUrl || config.baseUrl,
  5.             methods: ctx.options.methods || config.methods || 'POST',
  6.             header: ctx.options.header || config.header || {},
  7.             dataType: ctx.options.dataType || config.dataType || 'json',
  8.             noBaseUrl: false
  9.         };
  10.     },
  11.     // 你配置的
  12.     ...interceptors.request,
  13.     async (ctx) => {
  14.         let {options} = ctx;
  15.         if (options.noBaseUrl) ctx.options.baseUrl = '';
  16.     }
复制代码

请求失败的并没有对外开放, 有兴趣可以改 index.js
  1.    /**
  2.     * 监听请求失败, 请求抛出
  3.     */
  4.     request.interceptors.response.fail.use(async (ctx) => {
  5.         return Promise.reject(ctx);
  6.     });
复制代码
自带实用工具
loop 队列(控制并发数)

loop.put((finsh)=> {})
执行finsh 表示该队列请求完毕, 该方法 返回传入的回调函数

loop.put.abort
移除该队列, 实际上是给传入的回调函数增加了 abort 方法

实例
  1.     let loop = new Loop(2); // 最大并发数2
  2.     loop.put((finsh)=> {
  3.         console.log(1);
  4.         
  5.         setTimeout(()=> {
  6.             finsh();
  7.         }, 2000)
  8.     })
  9.     loop.put((finsh)=> {
  10.         console.log(2);

  11.         setTimeout(()=> {
  12.             finsh();
  13.         }, 2000)
  14.     })
  15.     loop.put((finsh)=> {
  16.         console.log(3);

  17.         setTimeout(()=> {
  18.             finsh();
  19.         }, 2000)
  20.     })

  21.     loop.put((finsh)=> {}).abort();
复制代码
等待2秒后 才打印 3, finsh需手动执行, 表示该队列执行完成, 释放, 执行下一个方法

message.js (发布订阅, 从腾讯视频大大那边直接拿来用)
  1.     message.on('name', ()=> {});
  2.     message.emit('name');
复制代码

wx-request-master.zip (18.56 KB, 下载次数: 74)
回复

使用道具 举报

最佳答案
0 

0

主题

66

帖子

74

积分

等待验证会员

积分
74
发表于 2019-9-23 14:37:49 | 显示全部楼层
感谢技术大拿分享资料
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

363

帖子

7519

积分

S1

积分
7519
发表于 2019-9-25 08:53:26 | 显示全部楼层
微信小程序 请求 封装, promise, 请求并发限
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

363

帖子

7519

积分

S1

积分
7519
发表于 2019-9-25 08:53:30 | 显示全部楼层
微信小程序 请求 封装, promise, 请求并发限
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

363

帖子

7519

积分

S1

积分
7519
发表于 2019-9-25 08:53:33 | 显示全部楼层
微信小程序 请求 封装, promise, 请求并发限
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

363

帖子

7519

积分

S1

积分
7519
发表于 2019-9-25 08:53:36 | 显示全部楼层
微信小程序 请求 封装, promise, 请求并发限
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

603

帖子

372

积分

等待验证会员

积分
372
发表于 2019-9-28 17:38:27 | 显示全部楼层
的非官方的是个符合
回复 支持 反对

使用道具 举报

最佳答案
0 

0

主题

603

帖子

372

积分

等待验证会员

积分
372
发表于 2019-9-28 17:38:30 | 显示全部楼层

的非官方的是个符合
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



www.henkuai.com—微信开发者的分享交流平台,专注微信开发生态。

天津市滨海新区
中新生态城中成大道生态建设公寓9号楼3层301

微信公众号

广告推广
QQ:805874290

市场合作
zhongcong@henkuai.com