经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Omi » 查看文章
微信小程序网络层封装的实现(promise, 登录锁)
来源:jb51  时间:2019/5/9 8:30:35  对本文有异议

一、对小程序的request的封装

写过小程序的应该知道,微信的request不封装基本上不能用,写的显的太冗长,而且是回调式的,回调地狱什么的就不说了,可读性差。

下面是我的封装代码,顺便支持一下promise。

  1. function baseRequest({ url, method, header, data, complete }, resolve, reject) {
  2. wx.request({
  3. url,
  4. method,
  5. header,
  6. data,
  7. success: function (res) {
  8. // 需要判断服务器code的用这一段
  9. // 我司服务器返回0表示真正的成功,其他code表示各种错误码
  10. // if (res.data.code === 0) {
  11. // resolve(res)
  12. // } else {
  13. // reject(res)
  14. // }
  15. resolve(res)
  16. },
  17. fail: function (res) {
  18. reject(res)
  19. },
  20. complete: function (res) {
  21. complete(res)
  22. }
  23. })
  24. }
  25.  
  26. function requestPromise( options ) {
  27. let req = new Promise((resolve, reject) => {
  28. baseRequest(options, resolve, reject)
  29. })
  30. return req
  31. }
  32.  
  33. function get(options) {
  34. options.method = 'GET'
  35. return requestPromise(options)
  36. }
  37.  
  38. function post(options) {
  39. options.method = 'POST'
  40. if (!options.header) {
  41. options.header = {}
  42. }
  43. options.header["Content-Type"] = "application/x-www-form-urlencoded"
  44. return requestPromise(options)
  45. }
  46.  
  47. function put(options) {
  48. options.method = 'PUT'
  49. if (!options.header) {
  50. options.header = {}
  51. }
  52. options.header["Content-Type"] = "application/x-www-form-urlencoded"
  53. return requestPromise(options)
  54. }
  55.  
  56.  
  57. module.exports = {
  58. get,
  59. post,
  60. put
  61. }
  62.  

如何使用:

1. 将上面的代码写到一个独立的文件里,我的命名为network.js。

2. 然后将其绑定到全局的 wx 对象身上。 wx.Network = require('./network.js')。(在app.js里面绑定)

3. 实例如下

  1. wx.Network.get({
  2. url: 'xxx.xxx.xxx', // 请求路径
  3. data: {
  4. a: "a" // 参数列表
  5. }
  6. }).then(res => {
  7. console.log("请求成功")
  8. }).catch(res => {
  9. console.log("请求失败")
  10. })

二、登录锁

基本的request请求封装完了后,还有一些特殊的需求,比如

1. 在首页我会进行登录, 登录后获得token, 然后我拿着token去请求其他需要token才可以请求的接口 (比如个人购物信息)

2. 这个时候一种做法是登录完成前不进行需要token的请求,并且有蒙板进行拦截操作(正在登录ing...)

3. 对于我公来说这种方法有一个致命的弊端,就是在高并发的情况下,服务器的压力很大,首页的登录接口很慢才有返回(进首页即自动登录),这个时候,用户看到的界面就是loading,而且可能时间比较长,如果用户对你的产品粘性不高,绝大部分人直接就走了

4. 为了优化这种情况下的用户体验,我们全面取消了登录的loading,替换成了“登录锁”的形式

5. 效果为未登录调用需要token的接口时,不请求,直到登录完成后才会请求

6. 即如果这个请求需要token,那么先判断有没有登录,如果没有登录,启动定时器一段时间后(200ms),再次判断,如果已经登录,发出请求,如果没有,重复以上操作

加了登录锁后的代码如下: ( 添加了新的 wait 函数,调用get,post,put时增加第二个参数,表示是否需要token )

  1. function baseRequest({ url, method, header, data, complete }, resolve, reject) {
  2. wx.request({
  3. url,
  4. method,
  5. header,
  6. data,
  7. success: function (res) {
  8. // 需要判断服务器code的用这一段
  9. // 我司服务器返回0表示真正的成功,其他code表示各种错误码
  10. // if (res.data.code === 0) {
  11. // resolve(res)
  12. // } else {
  13. // reject(res)
  14. // }
  15. resolve(res)
  16. },
  17. fail: function (res) {
  18. reject(res)
  19. },
  20. complete: function (res) {
  21. complete(res)
  22. }
  23. })
  24. }
  25.  
  26. function wait(options, needToken, resolve, reject) {
  27. if (needToken) {
  28. var token = wx.getStorageSync('token')
  29. if (!token) {
  30. setTimeout(() => {
  31. wait.apply(null, arguments)
  32. }, 200)
  33. } else {
  34. if (!options.header) {
  35. options.header = {}
  36. }
  37. options.header["token"] = token
  38. baseRequest(options, resolve, reject)
  39. }
  40. } else {
  41. baseRequest(options, resolve, reject)
  42. }
  43. }
  44.  
  45. function requestPromise( options, needToken = true ) {
  46. let req = new Promise((resolve, reject) => {
  47. wait(options, needToken, resolve, reject)
  48. })
  49. return req
  50. }
  51.  
  52. function get(options, needToken) {
  53. options.method = 'GET'
  54. return requestPromise(options, needToken)
  55. }
  56.  
  57. function post(options, needToken) {
  58. options.method = 'POST'
  59. if (!options.header) {
  60. options.header = {}
  61. }
  62. options.header["Content-Type"] = "application/x-www-form-urlencoded"
  63. return requestPromise(options, needToken)
  64. }
  65.  
  66. function put(options, needToken) {
  67. options.method = 'PUT'
  68. if (!options.header) {
  69. options.header = {}
  70. }
  71. options.header["Content-Type"] = "application/x-www-form-urlencoded"
  72. return requestPromise(options, needToken)
  73. }
  74.  
  75.  
  76. module.exports = {
  77. get,
  78. post,
  79. put
  80. }
  81.  

如何使用:(使用方式和上面一样,只是调用的时候多一个参数)

1. 将上面的代码写到一个独立的文件里,我的命名为network.js。

2. 然后将其绑定到全局的 wx 对象身上。 wx.Network = require('./network.js')。(在app.js里面绑定)

3. 实例如下

  1. wx.Network.get({
  2. url: 'xxx.xxx.xxx', // 请求路径
  3. data: {
  4. a: "a" // 参数列表
  5. }
  6. }, true // 增加第二个参数,true表示需要token, false表示不需要
  7. ).then(res => {
  8. console.log("请求成功")
  9. }).catch(res => {
  10. console.log("请求失败")
  11. })

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号