微信小程序网络层封装的实现(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 相关文章推荐
初窥JQuery(二) 事件机制(1)
Nov 25 Javascript
jquery1.83 之前所有与异步列队相关的模块详细介绍
Nov 13 Javascript
HTML Color Picker(js拾色器效果)
Aug 27 Javascript
javascript实现页面内关键词高亮显示代码
Apr 03 Javascript
js仿苹果iwatch外观的计时器代码分享
Aug 26 Javascript
基于jquery实现简单的分页控件
Mar 17 Javascript
Js类的静态方法与实例方法区分及jQuery拓展的两种方法
Jun 03 Javascript
你可能不知道的JSON.stringify()详解
Aug 17 Javascript
微信小程序实现动态改变view标签宽度和高度的方法【附demo源码下载】
Dec 05 Javascript
layui 给数据表格加序号的方法
Aug 20 Javascript
vue-cli 为项目设置别名的方法
Oct 15 Javascript
如何使用JavaScript检测空闲的浏览器选项卡
May 28 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中用hash实现的数组
2011/07/17 PHP
javascript之卸载鼠标事件的代码
2007/05/14 Javascript
js实现文本框选中的方法
2015/05/26 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
2015/07/28 Javascript
jQuery div拖拽用法实例
2016/01/14 Javascript
利用JS提交表单的几种方法和验证(必看篇)
2016/09/17 Javascript
Javascript(es2016) import和require用法和区别详解
2017/08/11 Javascript
在Vue组件化中利用axios处理ajax请求的使用方法
2017/08/25 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
2020/09/21 Javascript
JavaScript获取时区实现过程解析
2020/09/24 Javascript
[01:24]DOTA2上海特锦赛OG战队抵达 专车接机入驻总统套房
2016/02/23 DOTA
Python中用max()方法求最大值的介绍
2015/05/15 Python
python编程开发之类型转换convert实例分析
2015/11/13 Python
基于pycharm导入模块显示不存在的解决方法
2018/10/13 Python
Python 实现的 Google 批量翻译功能
2019/08/26 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
pandas中read_csv、rolling、expanding用法详解
2020/04/21 Python
python安装后的目录在哪里
2020/06/21 Python
新加坡时尚网上购物:Zalora新加坡
2016/07/26 全球购物
台湾流行服饰购物平台:OB严选
2018/01/21 全球购物
世界经理人咨询有限公司面试
2014/09/23 面试题
土木工程专业自荐信
2013/10/04 职场文书
总经理岗位职责
2013/11/09 职场文书
毕业自我鉴定总结
2014/03/24 职场文书
初三学生个人自我评定
2014/04/06 职场文书
老师对学生的评语
2014/04/18 职场文书
运动员口号
2014/06/09 职场文书
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
内勤岗位职责
2015/02/10 职场文书
骨干教师个人总结
2015/02/11 职场文书
房地产置业顾问工作总结
2015/10/23 职场文书
浅谈Python列表嵌套字典转化的问题
2021/04/07 Python
python3.9之你应该知道的新特性详解
2021/04/29 Python
浅谈Python类的单继承相关知识
2021/05/12 Python
CKAD认证中部署k8s并配置Calico插件
2022/03/31 Servers
MySQL中IO问题的深入分析与优化
2022/04/02 MySQL