微信小程序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 相关文章推荐
jQuery动态设置form表单的enctype值(实现代码)
Jul 04 Javascript
$.get获取一个文件的内容示例代码
Sep 11 Javascript
JavaScript常用的返回,自动跳转,刷新,关闭语句汇总
Jan 13 Javascript
js显示文本框提示文字的方法
May 07 Javascript
jQuery实现tab选项卡效果的方法
Jul 08 Javascript
jqGrid表格应用之新增与删除数据附源码下载
Dec 02 Javascript
基于AngularJS实现的工资计算器实例
Jun 16 Javascript
Angular.js通过自定义指令directive实现滑块滑动效果
Oct 13 Javascript
Es6 Generator函数详细解析
Feb 24 Javascript
ES6 Object属性新的写法实例小结
Jun 25 Javascript
微信公众号网页分享功能开发的示例代码
May 27 Javascript
JS中循环遍历数组的四种方式总结
Jan 23 Javascript
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
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
深入浅析PHP7.0新特征(五大新特征)
2015/10/29 PHP
php实现算术验证码功能
2018/12/05 PHP
Aster vs Newbee BO5 第三场2.19
2021/03/10 DOTA
JavaScript中的ArrayBuffer详细介绍
2014/12/08 Javascript
setTimeout内不支持jquery的选择器的解决方案
2015/04/28 Javascript
使用Raygun对Node.js应用进行错误处理的方法
2015/06/23 Javascript
js实现显示当前状态的导航效果代码
2015/08/28 Javascript
限制文本框只能输入数字||只能是数字和小数点||只能是整数和浮点数
2016/05/27 Javascript
DOM中事件处理概览与原理的全面解析
2016/08/16 Javascript
Bootstrap jquery.twbsPagination.js动态页码分页实例代码
2017/02/20 Javascript
详解node.js搭建代理服务器请求数据
2017/04/08 Javascript
js实现图片粘贴上传到服务器并展示的实例
2017/11/08 Javascript
详解webpack运行Babel教程
2018/06/13 Javascript
jQuery常见的遍历DOM操作详解
2018/09/05 jQuery
vue 实现强制类型转换 数字类型转为字符串
2019/11/07 Javascript
vue项目中使用particles实现粒子背景效果及遇到的坑(按钮没有点击响应)
2020/02/11 Javascript
JavaScript oncopy事件用法实例解析
2020/05/13 Javascript
[48:11]完美世界DOTA2联赛 Magma vs GXR 第二场 11.07
2020/11/10 DOTA
Python实现将目录中TXT合并成一个大TXT文件的方法
2015/07/15 Python
git进行版本控制心得详谈
2017/12/10 Python
python使用writerows写csv文件产生多余空行的处理方法
2019/08/01 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
2019/09/25 Python
python实现将视频按帧读取到自定义目录
2019/12/10 Python
html5 video标签屏蔽右键视频另存为的js代码
2013/11/12 HTML / CSS
实例讲解使用SVG制作loading加载动画的方法
2016/04/05 HTML / CSS
英国女士和男士时尚服装网上购物:Top Labels Online
2018/03/25 全球购物
Linux机考试题
2015/07/17 面试题
为什么要使用servlet
2016/01/17 面试题
外贸业务员岗位职责
2013/11/24 职场文书
车间统计员岗位职责
2014/01/05 职场文书
毕业生个人求职信范文分享
2014/01/05 职场文书
机修工工作职责
2014/02/21 职场文书
职场:企业印章管理制度(模板)
2019/10/18 职场文书
《好妈妈胜过好老师》:每个孩子的优秀都是有源头的
2020/01/03 职场文书
Python实现批量自动整理文件
2022/03/16 Python