微信小程序网络层封装的实现(promise, 登录锁)


Posted in Javascript onMay 08, 2019

一、对小程序的request的封装

写过小程序的应该知道,微信的request不封装基本上不能用,写的显的太冗长,而且是回调式的,回调地狱什么的就不说了,可读性差。

下面是我的封装代码,顺便支持一下promise。

function baseRequest({ url, method, header, data, complete }, resolve, reject) {
 wx.request({
 url,
 method,
 header,
 data,
 success: function (res) {
  // 需要判断服务器code的用这一段
  // 我司服务器返回0表示真正的成功,其他code表示各种错误码
  // if (res.data.code === 0) {
  // resolve(res)
  // } else {
  // reject(res)
  // }
  resolve(res)
 },
 fail: function (res) {
  reject(res)
 },
 complete: function (res) {
  complete(res)
 }
 })
}

function requestPromise( options ) {
 let req = new Promise((resolve, reject) => {
 baseRequest(options, resolve, reject)
 })
 return req
}

function get(options) {
 options.method = 'GET'
 return requestPromise(options)
}

function post(options) {
 options.method = 'POST'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options)
}

function put(options) {
 options.method = 'PUT'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options)
}


module.exports = {
 get,
 post,
 put
}

如何使用:

1. 将上面的代码写到一个独立的文件里,我的命名为network.js。

2. 然后将其绑定到全局的 wx 对象身上。 wx.Network = require('./network.js')。(在app.js里面绑定)

3. 实例如下

wx.Network.get({
 url: 'xxx.xxx.xxx', // 请求路径
 data: {
  a: "a" // 参数列表
 }
 }).then(res => {
  console.log("请求成功")
 }).catch(res => {
  console.log("请求失败") 
 })

二、登录锁

基本的request请求封装完了后,还有一些特殊的需求,比如

1. 在首页我会进行登录, 登录后获得token, 然后我拿着token去请求其他需要token才可以请求的接口 (比如个人购物信息)

2. 这个时候一种做法是登录完成前不进行需要token的请求,并且有蒙板进行拦截操作(正在登录ing...)

3. 对于我公来说这种方法有一个致命的弊端,就是在高并发的情况下,服务器的压力很大,首页的登录接口很慢才有返回(进首页即自动登录),这个时候,用户看到的界面就是loading,而且可能时间比较长,如果用户对你的产品粘性不高,绝大部分人直接就走了

4. 为了优化这种情况下的用户体验,我们全面取消了登录的loading,替换成了“登录锁”的形式

5. 效果为未登录调用需要token的接口时,不请求,直到登录完成后才会请求

6. 即如果这个请求需要token,那么先判断有没有登录,如果没有登录,启动定时器一段时间后(200ms),再次判断,如果已经登录,发出请求,如果没有,重复以上操作

加了登录锁后的代码如下: ( 添加了新的 wait 函数,调用get,post,put时增加第二个参数,表示是否需要token )

function baseRequest({ url, method, header, data, complete }, resolve, reject) {
 wx.request({
 url,
 method,
 header,
 data,
 success: function (res) {
  // 需要判断服务器code的用这一段
  // 我司服务器返回0表示真正的成功,其他code表示各种错误码
  // if (res.data.code === 0) {
  // resolve(res)
  // } else {
  // reject(res)
  // }
  resolve(res)
 },
 fail: function (res) {
  reject(res)
 },
 complete: function (res) {
  complete(res)
 }
 })
}

function wait(options, needToken, resolve, reject) {
 if (needToken) {
 var token = wx.getStorageSync('token')
 if (!token) {
  setTimeout(() => {
  wait.apply(null, arguments)
  }, 200)
 } else {
  if (!options.header) {
  options.header = {}
  }
  options.header["token"] = token
  baseRequest(options, resolve, reject)
 }
 } else {
 baseRequest(options, resolve, reject)
 }
}

function requestPromise( options, needToken = true ) {
 let req = new Promise((resolve, reject) => {
 wait(options, needToken, resolve, reject)
 })
 return req
}

function get(options, needToken) {
 options.method = 'GET'
 return requestPromise(options, needToken)
}

function post(options, needToken) {
 options.method = 'POST'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options, needToken)
}

function put(options, needToken) {
 options.method = 'PUT'
 if (!options.header) {
 options.header = {}
 }
 options.header["Content-Type"] = "application/x-www-form-urlencoded"
 return requestPromise(options, needToken)
}


module.exports = {
 get,
 post,
 put
}

如何使用:(使用方式和上面一样,只是调用的时候多一个参数)

1. 将上面的代码写到一个独立的文件里,我的命名为network.js。

2. 然后将其绑定到全局的 wx 对象身上。 wx.Network = require('./network.js')。(在app.js里面绑定)

3. 实例如下

wx.Network.get({
 url: 'xxx.xxx.xxx', // 请求路径
 data: {
  a: "a" // 参数列表
 }
 }, true // 增加第二个参数,true表示需要token, false表示不需要
 ).then(res => {
  console.log("请求成功")
 }).catch(res => {
  console.log("请求失败") 
 })

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
改进:论坛UBB代码自动插入方式
Dec 22 Javascript
javascript attachEvent绑定多个事件执行顺序问题
Oct 20 Javascript
JS实现闪动的title消息提醒效果
Jun 20 Javascript
jQuery使用toggleClass方法动态添加删除Class样式的方法
Mar 26 Javascript
详解JavaScript中Hash Map映射结构的实现
May 21 Javascript
jquery操作select取值赋值与设置选中实例
Feb 28 Javascript
JS基于正则表达式的替换操作(replace)用法示例
Apr 28 Javascript
ReactJs设置css样式的方法
Jun 08 Javascript
基于input动态模糊查询的实现方法
Dec 12 Javascript
微信小程序显示倒计时功能示例【测试可用】
Dec 03 Javascript
JS实现简易留言板增删功能
Feb 08 Javascript
js+canvas实现五子棋小游戏
Aug 02 Javascript
详解微信小程序的不同函数调用的几种方法
May 08 #Javascript
微信小程序Page中data数据操作和函数调用方法
May 08 #Javascript
vue中使用props传值的方法
May 08 #Javascript
vue权限问题的完美解决方案
May 08 #Javascript
基于vue-cli 路由 实现类似tab切换效果(vue 2.0)
May 08 #Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
May 08 #Javascript
利用原生JavaScript实现造日历轮子实例代码
May 08 #Javascript
You might like
PHP扩展编写点滴 技巧收集
2010/03/09 PHP
浅析php插件 HTMLPurifier HTML解析器
2013/07/01 PHP
PHP连接和操作MySQL数据库基础教程
2014/09/29 PHP
PHP常见字符串操作函数与用法总结
2019/03/04 PHP
Yii框架参数配置文件params用法实例分析
2019/09/11 PHP
实例化php类时传参的方法分析
2020/06/05 PHP
用cookies实现的可记忆的样式切换效果代码下载
2007/12/24 Javascript
jquery 双色表格实现代码
2009/12/08 Javascript
!DOCTYPE声明对JavaScript的影响分析
2010/04/12 Javascript
javascript 事件处理、鼠标拖动效果实现方法详解
2012/05/11 Javascript
纯JS实现五子棋游戏兼容各浏览器(附源码)
2013/04/24 Javascript
javascript中Number对象的toString()方法分析
2014/12/20 Javascript
js实现大转盘抽奖游戏实例
2015/06/24 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法
2016/12/24 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
2017/09/13 Javascript
安装vue-cli报错 -4058 的解决方法
2017/10/19 Javascript
React数据传递之组件内部通信的方法
2017/12/31 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
2019/01/24 Javascript
解决layui使用layui-icon出现默认图标的问题
2019/09/11 Javascript
详解python进行mp3格式判断
2016/12/23 Python
Python编程生成随机用户名及密码的方法示例
2017/05/05 Python
Python2和Python3中urllib库中urlencode的使用注意事项
2018/11/26 Python
Python List cmp()知识点总结
2019/02/18 Python
简单了解pytest测试框架setup和tearDown
2020/04/14 Python
Django配置跨域并开发测试接口
2020/11/04 Python
html5 canvas绘制矩形和圆形的实例代码
2016/06/16 HTML / CSS
挂靠协议书范本
2014/04/22 职场文书
单位委托书格式范本
2014/09/29 职场文书
2015学校年度工作总结
2015/05/11 职场文书
开学典礼观后感
2015/06/15 职场文书
2015年学校教科室工作总结
2015/07/20 职场文书
《观潮》教学反思
2016/02/17 职场文书
GTX1650super好不好 gtx1650super显卡属于什么级别
2022/04/08 数码科技
使用Mysql计算地址的经纬度距离和实时位置信息
2022/04/29 MySQL