微信小程序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 相关文章推荐
JS 继承实例分析
Nov 04 Javascript
30分钟就入门的正则表达式基础教程
Feb 25 Javascript
通过javascript获取iframe里的值示例代码
Jun 24 Javascript
javascript:void(0)使用探讨
Aug 27 Javascript
基于Vuejs实现购物车功能
Aug 02 Javascript
深入学习js瀑布流布局
Oct 14 Javascript
Angularjs2不同组件间的通信实例代码
May 06 Javascript
js实现本地时间同步功能
Aug 26 Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
Dec 14 Javascript
Vue项目中跨域问题解决方案
Jun 05 Javascript
JavaScript实现的开关灯泡点击切换特效示例
Jul 08 Javascript
基于Vue实现微前端的示例代码
Apr 24 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
Protoss建筑一览
2020/03/14 星际争霸
关于我转生变成史莱姆这档事:第二季PV上线,萌王2021年回归
2020/05/06 日漫
php开发过程中关于继承的使用方法分享
2011/06/17 PHP
php守护进程 加linux命令nohup实现任务每秒执行一次
2011/07/04 PHP
php使用gettimeofday函数返回当前时间并存放在关联数组里
2015/03/19 PHP
PHP7新功能总结
2019/04/14 PHP
!DOCTYPE声明对JavaScript的影响分析
2010/04/12 Javascript
纯JS实现的批量图片预览加载功能
2011/08/14 Javascript
Array.prototype.concat不是通用方法反驳[译]
2012/09/20 Javascript
JQuery实现表格中相同单元格合并示例代码
2013/06/26 Javascript
解析页面加载与js函数的执行 onload or ready
2013/12/12 Javascript
使用js完成节点的增删改复制等的操作
2014/01/02 Javascript
Jquery实现Div上下移动示例
2014/04/23 Javascript
详解addEventListener的三个参数之useCapture
2015/03/16 Javascript
微信小程序 网络请求(post请求,get请求)
2017/01/17 Javascript
javaScript实现滚动条事件详解
2020/03/24 Javascript
JS实现图片转换成base64的各种应用场景实例分析
2018/06/22 Javascript
vue实现codemirror代码编辑器中的SQL代码格式化功能
2019/08/27 Javascript
修改layui的后台模板的左侧导航栏可以伸缩的方法
2019/09/10 Javascript
vue框架制作购物车小球动画效果实例代码
2019/09/26 Javascript
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
2019/11/18 NodeJs
重命名批处理python脚本
2013/04/05 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
pandas对指定列进行填充的方法
2018/04/11 Python
numpy.std() 计算矩阵标准差的方法
2018/07/11 Python
Python3.7实现中控考勤机自动连接
2018/08/28 Python
python__name__原理及用法详解
2019/11/02 Python
迪拜领先运动补剂零售品牌中文站:Sporter商城
2019/08/20 全球购物
常见的软件开发流程有哪些
2015/11/14 面试题
值传递还是引用传递
2015/02/08 面试题
老师的检讨书
2014/02/23 职场文书
党的群众路线教育实践活动对照检查材料(四风)
2014/09/27 职场文书
开展党的群众路线教育实践活动工作总结
2014/11/05 职场文书
2015年国税春训心得体会
2015/03/09 职场文书
搭讪开场白台词大全
2015/05/28 职场文书
为什么node.js不适合大型项目
2021/04/28 Javascript