微信小程序HTTP请求从0到1封装


Posted in Javascript onSeptember 09, 2019

前言

作为一个前端开发者,从最开始的js、jQuery一把梭,后来的vue、react、angular等MVVM、MVC框架,我们在开发工程中都离不开HTTP库的使用。

HTTP库

1、jQuery的$.ajax

调用了XMLHttpRequest对象,封装在相关函数在配置项中,一旦传入了必需选项,则直接调用相应的send()方法进行数据的请求

2、Axios

基于Promise的请求库,通过判断XMLHTTPRequest对象存在与否,来支持客户端和node服务端发送请求,封装的很不错的HTTP库,支持promise、拦截请求和响应等

小程序网络请求

wx.request({
 url: 'test.php', //仅为示例,并非真实的接口地址
 data: {
 x: '',
 y: ''
 },
 header: {
 'content-type': 'application/json' // 默认值
 },
 success (res) {
 console.log(res.data)
 }
})

小程序本身的请求已经封装的很不错了,使用起来和$.ajax相似,支持许多配置项的设置,但是缺少公共配置、响应和请求拦截等实用功能

第一步--创建请求实例

class Axios {
 constructor() {
  this.instance = null // 类的实例
  this.config = defaultConfig
 }

 create(instanceConfig) {
  const { config } = this
  // 创建实例的时候添加基本配置
  this.config = {
   ...config,
   ...instanceConfig
  }
  return this
 }

 // 单例
 static getInstance() {
  if (!this.instance) {
    this.instance = new Axios()
  }
  return this.instance
 }
}

创建实例

const axios = Axios.getInstance()

promise包装小程序请求

const dispatchRequest = function(config) {
 return new Promise((resolve, reject) => {
  wx.request({
   ...config,
   url: config.base + config.url,
   success: res => {
    resolve(res)
   },
   fail: res => {
    reject(res)
   }
  })
 })
}

给请求实例添加request方法

request(options) {
 const { config } = this
 // 实例请求的时候添加基本配置
 const requsetOptions = {
  ...config,
  ...options
 }
 return dispatchRequest(requsetOptions)
}

第二步--创建请求工具方法

创建实例,通过create设置基本配置项

const instance = (config = {}) => {
 return axios.create({
  base: globalApi,
  ...config
 })
}

创建请求工具方法,执行实例request

export function request(options) {
 const { baseConfig, url, method, data, isLogin } = options
 instance(baseConfig)
  .request({
   url,
   method: method || 'GET',
   data
  })
  .then(res => {
   options.success && options.success(res)
  })
  .catch(err => {
   if (options.error) {
    options.error(err)
   } else {
    errAlert()
   }
  })
 }
}

这样,一个请求的工具方法就完成了,但是这个方法现在只支持基本的请求和基本配置项的配置,还是缺少我们很常用的公共请求和响应的拦截。

第三部--添加请求和响应的拦截器

创建拦截器实例

class InterceptorManager {
 constructor() {
  this.fulfilled = null
  this.rejected = null
 }

 use(fulfilled, rejected) {
  this.fulfilled = fulfilled
  this.rejected = rejected
 }
}

在请求实例的构造方法中添加请求和响应拦截实例

constructor() {
 this.instance = null // 类的实例
 this.config = defaultConfig
 this.interceptors = {
  request: new InterceptorManager(),
  response: new InterceptorManager()
 }
}

在实例的request添加promise执行队列

request(options) {
  const { config, interceptors } = this
  // 实例请求的时候添加基本配置
  const requsetOptions = {
   ...config,
   ...options
  }

  const promiseArr = [] // promise存储队列

  // 请求拦截器
  promiseArr.push({
   fulfilled: interceptors.request.fulfilled,
   rejected: interceptors.request.rejected
  })

  // 请求
  promiseArr.push({
   fulfilled: dispatchRequest,
   rejected: null
  })

  // 回调拦截器
  promiseArr.push({
   fulfilled: interceptors.response.fulfilled,
   rejected: interceptors.response.rejected
  })

  let p = Promise.resolve(requsetOptions)
  promiseArr.forEach(ele => {
   p = p.then(ele['fulfilled'], ele['rejected'])
  })

  return p
 }

在请求工具方法中通过设置请求和响应的拦截方法

axios.interceptors.request.use(
 request => {
  return request
 },
 err => {
  console.error(err)
 }
)
axios.interceptors.response.use(
 response => {
  return response
 },
 err => {
  console.error(err)
 }
)

在请求拦截方法里面可以添加数据转换,在请求头部添加sign、token等,在响应拦截方法里面去做公共的数据处理等

最后

从零搭建一个简单的请求库很简单,但是想考虑的方方面面,设计好整个流程会比较麻烦,需要不断的改进和重构,本文的搭架过程参考了Axios的部分源码。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
一个可以兼容IE FF的加为首页与加入收藏实现代码
Nov 02 Javascript
JavaScript 原型继承
Dec 26 Javascript
JS匀速运动演示示例代码
Nov 26 Javascript
EasyUI布局 高度自适应
Jun 04 Javascript
D3.js实现散点图和气泡图的方法详解
Sep 21 Javascript
self.attachevent is not a function的解决方法
Apr 04 Javascript
Angular6中使用Swiper的方法示例
Jul 09 Javascript
详解小程序rich-text对富文本支持方案
Nov 28 Javascript
JavaScript私有变量实例详解
Jan 24 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
Aug 17 Javascript
vue 实现websocket发送消息并实时接收消息
Dec 09 Javascript
Vue实现简单购物车功能
Dec 13 Vue.js
JS回调函数 callback的理解与使用案例分析
Sep 09 #Javascript
世界上最短的数字判断js代码
Sep 09 #Javascript
JavaScript中判断为整数的多种方式及保留两位小数的方法
Sep 09 #Javascript
javascript删除数组元素的七个方法示例
Sep 09 #Javascript
微信小程序 select 下拉框组件功能
Sep 09 #Javascript
移动端手指操控左右滑动的菜单
Sep 08 #Javascript
swiper Scrollbar滚动条组件详解
Sep 08 #Javascript
You might like
用PHP和ACCESS写聊天室(一)
2006/10/09 PHP
PHP setTime 设置当前时间的代码
2012/08/27 PHP
php多线程实现方法及用法实例详解
2015/10/26 PHP
javascript循环变量注册dom事件 之强大的闭包
2010/09/08 Javascript
jQuery学习笔记之jQuery动画效果
2013/09/09 Javascript
JavaScript避免内存泄露及内存管理技巧
2014/09/05 Javascript
跟我学习javascript解决异步编程异常方案
2015/11/23 Javascript
js获取iframe中的window对象的实现方法
2016/05/20 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
2016/11/17 Javascript
angular 基于ng-messages的表单验证实例
2017/05/04 Javascript
详解Vue 动态组件与全局事件绑定总结
2018/11/11 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
JavaScript模板引擎原理与用法详解
2018/12/24 Javascript
使用React手写一个对话框或模态框的方法示例
2019/04/25 Javascript
JavaScript浅层克隆与深度克隆示例详解
2020/09/01 Javascript
[01:14:35]DOTA2上海特级锦标赛B组资格赛#1 Alliance VS Fnatic第一局
2016/02/26 DOTA
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
2014/01/22 Python
python3实现读取chrome浏览器cookie
2016/06/19 Python
python常用知识梳理(必看篇)
2017/03/23 Python
Python实现利用163邮箱远程关电脑脚本
2018/02/22 Python
django框架面向对象ORM模型继承用法实例分析
2019/07/29 Python
详解Python3迁移接口变化采坑记
2019/10/11 Python
python如何操作mysql
2020/08/17 Python
纯CSS3绘制打火机动画火焰效果
2016/07/18 HTML / CSS
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
独特的礼品和创新的科技产品:The Grommet
2018/02/24 全球购物
学校后勤人员职责
2013/12/27 职场文书
预备党员思想汇报范文
2014/01/11 职场文书
小学生安全保证书
2014/02/01 职场文书
库房保管员岗位职责
2014/04/07 职场文书
小学教师师德师风演讲稿
2014/08/22 职场文书
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
2014司机年终工作总结
2014/12/05 职场文书
劳动保障事务所个人工作总结
2015/08/12 职场文书
python爬取豆瓣电影TOP250数据
2021/05/23 Python
变长双向rnn的正确使用姿势教学
2021/05/31 Python