微信小程序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 相关文章推荐
用JavaScript计算在UTF-8下存储字符串占用字节数
Aug 08 Javascript
js获取当前页面路径示例讲解
Jan 08 Javascript
JavaScript实现简单的tab选项卡切换
Jan 05 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
Jul 09 Javascript
JS实现复制功能
Mar 01 Javascript
jquery easyui dataGrid动态改变排序字段名的方法
Mar 02 Javascript
详解Vue双向数据绑定原理解析
Sep 11 Javascript
vue forEach循环数组拿到自己想要的数据方法
Sep 21 Javascript
利用js-cookie实现前端设置缓存数据定时失效
Jun 18 Javascript
JavaScript中的null和undefined用法解析
Sep 30 Javascript
jQuery轮播图功能制作方法详解
Dec 03 jQuery
基于vue+echarts 数据可视化大屏展示的方法示例
Mar 09 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
php模板中出现空行解决方法
2011/03/08 PHP
zf框架的zend_cache缓存使用方法(zend框架)
2014/03/14 PHP
用PHP解决的一个栈的面试题
2014/07/02 PHP
php实现HTML实体编号与非ASCII字符串相互转换类实例
2016/11/02 PHP
form自动提交实例讲解
2017/07/10 PHP
laravel 实现关闭CSRF(全部关闭、部分关闭)
2019/10/21 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
JS window.opener返回父页面的应用
2009/10/24 Javascript
JavaScript的eval JSON object问题
2009/11/15 Javascript
js图片延迟加载的实现方法及思路
2013/07/22 Javascript
JavaScript中Math对象方法使用概述
2014/01/02 Javascript
js获取内联样式的方法
2015/01/27 Javascript
JS实现同一个网页布局滑动门和TAB选项卡实例
2015/09/23 Javascript
Bootstrap每天必学之js插件
2015/11/30 Javascript
详解nodejs与javascript中的aes加密
2016/05/22 NodeJs
jquery插件ContextMenu设置右键菜单
2017/03/13 Javascript
Vue下的国际化处理方法
2017/12/18 Javascript
浅谈Vue.js中ref ($refs)用法举例总结
2017/12/19 Javascript
对Angular中单向数据流的深入理解
2018/03/31 Javascript
Node.Js中实现端口重用原理详解
2018/05/03 Javascript
原生JavaScript实现滑动拖动验证的示例代码
2019/12/06 Javascript
js动态添加带圆圈序号列表的实例代码
2021/02/18 Javascript
python实现读取大文件并逐行写入另外一个文件
2018/04/19 Python
Python函数中参数是传递值还是引用详解
2019/07/02 Python
Python CVXOPT模块安装及使用解析
2019/08/01 Python
python随机数分布random均匀分布实例
2019/11/27 Python
Tensorflow矩阵运算实例(矩阵相乘,点乘,行/列累加)
2020/02/05 Python
python 根据列表批量下载网易云音乐的免费音乐
2020/12/03 Python
苹果中国官方网站:Apple中国
2016/07/22 全球购物
澳大利高级泳装品牌:Bondi Born
2018/05/23 全球购物
澳大利亚最早和最古老的巨型游戏专家:Yardgames
2020/02/20 全球购物
介绍一下gcc特性
2012/01/20 面试题
五年级音乐教学反思
2014/02/06 职场文书
卫生保健工作总结2015
2015/05/18 职场文书
详解Vue的options
2021/05/15 Vue.js
MySQL官方导出工具mysqlpump的使用
2021/05/21 MySQL