微信小程序网络层封装的实现(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 数组的方法集合
Jun 05 Javascript
类似php的js数组的in_array函数自定义方法
Dec 27 Javascript
JavaScript中九种常用排序算法
Sep 02 Javascript
javascript倒计时效果实现
Nov 12 Javascript
jQuery zTree加载树形菜单功能
Feb 25 Javascript
Angular实现跨域(搜索框的下拉列表)
Feb 16 Javascript
微信小程序获取用户openId的实现方法
May 23 Javascript
webpack4+express+mongodb+vue实现增删改查的示例
Nov 08 Javascript
Vue 实现点击空白处隐藏某节点的三种方式(指令、普通、遮罩)
Oct 23 Javascript
vue在线动态切换主题色方案
Mar 26 Javascript
ant design中upload组件上传大文件,显示进度条进度的实例
Oct 29 Javascript
JavaScript 绘制饼图的示例
Feb 19 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
Laravel 5框架学习之Blade 简介
2015/04/08 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
javascript延时重复执行函数 lLoopRun.js
2007/06/29 Javascript
JSON 和 JavaScript eval使用说明
2010/06/13 Javascript
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
JS获取当前日期时间并定时刷新示例
2021/03/04 Javascript
Javascript 读取操作Sql中的Xml字段
2014/10/09 Javascript
jQuery实现的五子棋游戏实例
2015/06/13 Javascript
jquery实现文本框textarea自适应高度
2016/03/09 Javascript
关于cookie的初识和运用(js和jq)
2016/04/07 Javascript
JavaScript 继承详解(五)
2016/10/11 Javascript
Ztree新增角色和编辑角色回显问题的解决
2016/10/25 Javascript
老生常谈原生JS执行环境与作用域
2016/11/22 Javascript
jQuery源码分析之init的详细介绍
2017/02/13 Javascript
Node.js使用NodeMailer发送邮件实例代码
2017/03/06 Javascript
JS二叉树的简单实现方法示例
2017/04/05 Javascript
浅谈Vue.js中如何实现自定义下拉菜单指令
2019/01/06 Javascript
详解package.json版本号规则
2019/08/01 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
vue语法自动转typescript(解放双手)
2019/09/18 Javascript
jQuery实现鼠标放置名字上显示详细内容气泡提示框效果的方法分析
2020/04/04 jQuery
python使用心得之获得github代码库列表
2014/06/25 Python
Python实现的桶排序算法示例
2017/11/29 Python
python生成密码字典的方法
2018/07/06 Python
浅谈pycharm的xmx和xms设置方法
2018/12/03 Python
对web.py设置favicon.ico的方法详解
2018/12/04 Python
使用Python向DataFrame中指定位置添加一列或多列的方法
2019/01/29 Python
python找出一个列表中相同元素的多个索引实例
2019/06/11 Python
pandas读取csv文件提示不存在的解决方法及原因分析
2020/04/21 Python
python BeautifulSoup库的安装与使用
2020/12/17 Python
DRF使用simple JWT身份验证的实现
2021/01/14 Python
一份Java笔试题
2012/02/21 面试题
应届毕业生求职信范文
2014/05/08 职场文书
logback 实现给变量指定默认值
2021/08/30 Java/Android
HTML页面中使两个div并排显示的实现
2022/05/15 HTML / CSS
GO中sync包自由控制并发示例详解
2022/08/05 Golang