微信小程序网络层封装的实现(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 相关文章推荐
javascript 表格排序和表头浮动效果(扩展SortTable)
Apr 07 Javascript
JS刷新当前页面的几种方法总结
Dec 24 Javascript
JS使用正则表达式除去字符串中重复字符的方法
Nov 05 Javascript
angularjs实现文字上下无缝滚动特效代码
Sep 04 Javascript
BootStrap3使用错误记录及解决办法
Dec 22 Javascript
详解百度百科目录导航树小插件
Jan 08 Javascript
原生JavaScript实现AJAX、JSONP
Feb 07 Javascript
解决BootStrap Fileinput手机图片上传显示旋转问题
Jun 01 Javascript
javascript中mouseenter与mouseover的异同
Jun 06 Javascript
javascript按顺序加载运行js方法
Dec 01 Javascript
去掉vue 中的代码规范检测两种方法(Eslint验证)
Mar 21 Javascript
基于原生js实现九宫格算法代码实例
Jul 03 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 xml留言板 xml存储数据的简单例子
2009/08/24 PHP
yii实现CheckBox复选框在同一行显示的方法
2014/12/03 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
php文件后缀不强制为.php的实操方法
2019/09/18 PHP
jquery multiSelect 多选下拉框
2010/07/09 Javascript
jquery动画4.升级版遮罩效果的图片走廊--带自动运行效果
2012/08/24 Javascript
js中apply方法的使用详细解析
2013/11/04 Javascript
JavaScript中number转换成string介绍
2014/12/31 Javascript
js控制文本框只输入数字和小数点的方法
2015/03/10 Javascript
使用Chrome浏览器调试AngularJS应用的方法
2015/06/18 Javascript
jQuery EasyUI封装简化操作
2016/09/18 Javascript
js 轮播效果实例分享
2016/12/28 Javascript
JavaScript轻松创建级联函数的方法示例
2017/02/10 Javascript
Vue 过渡实现轮播图效果
2017/03/27 Javascript
BootStrap中Table隐藏后显示问题的实现代码
2017/08/31 Javascript
axios发送post请求,提交图片类型表单数据方法
2018/03/16 Javascript
JavaScript累加、迭代、穷举、递归等常用算法实例小结
2018/05/08 Javascript
node前端模板引擎Jade之标签的基本写法
2018/05/11 Javascript
VUE 自定义组件模板的方法详解
2019/08/30 Javascript
JS中FileReader类实现文件上传及时预览功能
2020/03/27 Javascript
Bootstrap table 服务器端分页功能实现方法示例
2020/06/01 Javascript
vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据操作
2020/07/31 Javascript
js 函数性能比较方法
2020/08/24 Javascript
[07:31]DOTA2卡尔工作室 英雄介绍主宰篇
2013/06/25 DOTA
[16:01]夜魇凡尔赛茶话会 第二期01:你比划我猜
2021/03/11 DOTA
python读取文件名称生成list的方法
2018/04/27 Python
详解如何在Apache中运行Python WSGI应用
2019/01/02 Python
Django框架自定义session处理操作示例
2019/05/27 Python
使用NumPy读取MNIST数据的实现代码示例
2019/11/20 Python
python 计算积分图和haar特征的实例代码
2019/11/20 Python
Python爬取微信小程序Charles实现过程图解
2020/09/29 Python
您的健身减肥和健康饮食专家:vitafy
2017/06/06 全球购物
英国最大的婴儿监视器网上商店:Baby Monitors Direct
2018/04/24 全球购物
学年末自我鉴定
2014/01/21 职场文书
公安局副政委班子个人对照检查材料
2014/10/04 职场文书
利用Python判断你的密码难度等级
2021/06/02 Python