微信小程序网络层封装的实现(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 相关文章推荐
jQueryUI的Dialog的简单封装
Jun 07 Javascript
浅析javascript中函数声明和函数表达式的区别
Feb 15 Javascript
JavaScript面对国际化编程时的一些建议
Jun 24 Javascript
深入剖析javascript中的exec与match方法
May 18 Javascript
js验证框架之RealyEasy验证详解
Jun 08 Javascript
Bootstrap编写一个同时适用于PC、平板、手机的登陆页面
Jun 30 Javascript
BootstrapValidator超详细教程(推荐)
Dec 07 Javascript
react 父组件与子组件之间的值传递的方法
Sep 14 Javascript
使用proxy实现一个更优雅的vue【推荐】
Jun 19 Javascript
vue页面更新patch的实现示例
Mar 25 Javascript
JS快速实现简单计算器
Apr 08 Javascript
vue iview实现动态新增和删除
Jun 17 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
PHP4实际应用经验篇(6)
2006/10/09 PHP
php echo()和print()、require()和include()函数区别说明
2010/03/27 PHP
php字符编码转换之gb2312转为utf8
2013/10/28 PHP
PHP获取photoshop写入图片文字信息的方法
2015/03/31 PHP
PHP检测用户是否关闭浏览器的方法
2016/02/14 PHP
详解Laravel视图间共享数据与视图Composer
2016/08/04 PHP
PHP中16个高危函数整理
2019/09/19 PHP
IE和firefox浏览器的event事件兼容性汇总
2009/12/06 Javascript
原生js实现给指定元素的后面追加内容
2013/04/10 Javascript
CheckBoxList多选样式jquery、C#获取选择项
2013/09/06 Javascript
JS中typeof与instanceof之间的区别总结
2013/11/14 Javascript
jquery分页插件jpaginate在IE中不兼容问题
2014/04/22 Javascript
VS2008中使用JavaScript调用WebServices
2014/12/18 Javascript
jQuery实现设置、移除文本框默认值功能
2015/01/13 Javascript
js采用concat和sort将N个数组拼接起来的方法
2016/01/21 Javascript
详解nodejs爬虫程序解决gbk等中文编码问题
2017/04/06 NodeJs
详解Node全局变量global模块
2017/09/28 Javascript
微信小程序实现人脸识别
2018/05/25 Javascript
NodeJS 实现多语言的示例代码
2018/09/11 NodeJs
Vue动画事件详解及过渡动画实例
2019/02/09 Javascript
js实现旋转的星空效果
2019/11/01 Javascript
[05:11]TI9战队采访——VIRTUSPRO
2019/08/22 DOTA
python正则表达式re模块详细介绍
2014/05/29 Python
Python 和 JS 有哪些相同之处
2017/11/23 Python
简单了解django索引的相关知识
2019/07/17 Python
使用 Python 遍历目录树的方法
2020/02/29 Python
Python统计学一数据的概括性度量详解
2020/03/03 Python
python如何解析复杂sql,实现数据库和表的提取的实例剖析
2020/05/15 Python
三月法制宣传月活动总结
2014/07/03 职场文书
党员批评与自我批评发言
2014/10/02 职场文书
爱国主义电影观后感
2015/06/18 职场文书
追讨欠款律师函
2015/06/24 职场文书
远程教育学习心得体会
2016/01/23 职场文书
提取视频中的音频 Python只需要三行代码!
2021/05/10 Python
Java面试题冲刺第十五天--设计模式
2021/08/07 面试题
Oracle配置dblink访问PostgreSQL的操作方法
2022/03/21 PostgreSQL