微信小程序网络层封装的实现(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 相关文章推荐
Prototype使用指南之form.js
Jan 10 Javascript
Jquery中对数组的操作代码
Aug 12 Javascript
在网站上应该用的30个jQuery插件整理
Nov 03 Javascript
jquery获取焦点和失去焦点事件代码
Apr 21 Javascript
分享javascript实现的冒泡排序代码并优化
Jun 05 Javascript
vue-cli创建的项目,配置多页面的实现方法
Mar 15 Javascript
在angular 6中使用 less 的实例代码
May 13 Javascript
Iview Table组件中各种组件扩展的使用
Oct 20 Javascript
详解js根据百度地图提供经纬度计算两点距离
May 13 Javascript
用VsCode编辑TypeScript的实现方法
May 07 Javascript
vue实现日历表格(element-ui)
Sep 24 Javascript
原生JavaScript实现轮播图
Jan 10 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 jQuery+Ajax结合写批量删除功能
2017/05/19 PHP
PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
2019/02/15 PHP
Javascript & DHTML 实例编程(教程)DOM基础和基本API
2007/06/02 Javascript
JavaScript判断DOM何时加载完毕的技巧
2012/11/11 Javascript
JS实现淘宝幻灯片效果的实现方法
2013/03/22 Javascript
js定时器的使用(实例讲解)
2014/01/06 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
2016/02/25 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
Nodejs抓取html页面内容(推荐)
2016/08/11 NodeJs
CodeMirror js代码加亮使用总结
2017/03/25 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
浅谈JavaScript find 方法不支持IE的问题
2017/09/28 Javascript
在一个页面实现两个zTree联动的方法
2017/12/20 Javascript
JS+CSS实现滚动数字时钟效果
2017/12/25 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
python中stdout输出不缓存的设置方法
2014/05/29 Python
分享一个常用的Python模拟登陆类
2015/03/29 Python
归纳整理Python中的控制流语句的知识点
2015/04/14 Python
Python守护线程用法实例
2017/06/23 Python
Python txt文件加入字典并查询的方法
2019/01/15 Python
PyQt5 对图片进行缩放的实例
2019/06/18 Python
python文件读写代码实例
2019/10/21 Python
python飞机大战pygame游戏背景设计详解
2019/12/17 Python
Matplotlib 绘制饼图解决文字重叠的方法
2020/07/24 Python
海淘零差价,宝贝全球购: 宝贝格子
2016/08/24 全球购物
纽约服装和生活方式品牌:Saturdays NYC
2017/08/13 全球购物
Falconeri美国官网:由羊绒和羊毛制成的针织服装
2018/04/08 全球购物
高级文秘工作总结的自我评价
2013/09/28 职场文书
关于逃课的检讨书
2014/01/23 职场文书
幼儿园中班教学反思
2014/02/10 职场文书
党的生日活动方案
2014/08/15 职场文书
老舍《猫》教学反思
2016/02/17 职场文书
话题作文之财富(600字)
2019/12/03 职场文书
mybatis 解决从列名到属性名的自动映射失败问题
2021/06/30 Java/Android
阿里云ECS云服务器快照的概念以及如何使用
2022/04/21 Servers
使用pd.merge表连接出现多余行的问题解决
2022/06/16 Python