微信小程序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 相关文章推荐
CSS+JS构建的图片查看器
Jul 22 Javascript
js利用div背景,做一个竖线的效果。
Nov 22 Javascript
javascript学习笔记(十) js对象 继承
Jun 19 Javascript
jQuery实现无限往下滚动效果代码
Apr 16 Javascript
bootstrap的常用组件和栅格式布局详解
May 02 Javascript
vue中如何实现后台管理系统的权限控制的方法示例
Sep 19 Javascript
JS中通过url动态获取图片大小的方法小结(两种方法)
Oct 31 Javascript
小程序实现人脸识别功能(百度ai)
Dec 23 Javascript
bootstrap table插件动态加载表头
Jul 19 Javascript
vue3.0中的双向数据绑定方法及优缺点
Aug 01 Javascript
Bootstrap简单实用的表单验证插件BootstrapValidator用法实例详解
Mar 29 Javascript
TypeScript 引用资源文件后提示找不到的异常处理技巧
Jul 15 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向js函数传参的几种方法
2014/08/10 PHP
ThinkPHP打水印及设置水印位置的方法
2016/10/14 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
PHP上传文件及图片到七牛的方法
2018/07/25 PHP
laradock环境docker-compose操作详解
2019/07/29 PHP
laravel框架 api自定义全局异常处理方法
2019/10/11 PHP
javascript 隐藏/显示指定的区域附HTML元素【legend】用法
2010/03/05 Javascript
读jQuery之九 一些瑕疵说明
2011/06/21 Javascript
javascript中不提供sleep功能如何实现这个功能
2014/05/27 Javascript
详解JavaScript时间格式化
2015/12/23 Javascript
利用Javascript仿Excel的数据透视分析功能
2016/09/07 Javascript
JS实现点击表头表格自动排序(含数字、字符串、日期)
2017/01/22 Javascript
解决给dom元素绑定click等事件无效问题的方法
2017/02/17 Javascript
无循环 JavaScript(map、reduce、filter和find)
2017/04/08 Javascript
Angular2生命周期钩子函数的详细介绍
2017/07/10 Javascript
浅谈Node异步编程的机制
2017/10/18 Javascript
Vue波纹按钮组件制作
2018/04/30 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
Python机器学习之决策树算法
2017/12/22 Python
Python设计模式之观察者模式简单示例
2018/01/10 Python
Python生成器generator用法示例
2018/08/10 Python
详解利用OpenCV提取图像中的矩形区域(PPT屏幕等)
2019/07/01 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
django自定义模板标签过程解析
2019/12/14 Python
python定义具名元组实例操作
2021/02/28 Python
10个很棒的 CSS3 开发工具 推荐
2011/05/16 HTML / CSS
ROSEFIELD手表荷兰官方网上商店:北欧极简设计女士腕表品牌
2018/01/24 全球购物
.net面试题
2015/12/22 面试题
亿企通软件测试面试题
2012/04/10 面试题
《雨点》教学反思
2014/02/12 职场文书
乡村卫生服务一体化管理实施方案
2014/03/30 职场文书
奥林匹克的口号
2014/06/13 职场文书
综治维稳工作汇报
2014/10/27 职场文书
2016高考寄语集锦
2015/12/04 职场文书
大学生暑期实践报告之企业经营管理
2019/08/08 职场文书
C3 线性化算法与 MRO之Python中的多继承
2021/10/05 Python