| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- class WxRequest {
- // 定义实例属性,用来设置默认请求参数
- defaults = {
- baseURL: '', // 请求基准地址
- url: '', // 接口的请求路径
- data: null, // 请求参数
- method: 'GET', // 默认的请求方法
- // 请求头
- header: {
- 'Content-type': 'application/json' // 设置数据的交互格式
- },
- timeout: 60000, // 默认的超时时长,小程序默认的超时时长是 1 分钟
- isLoading: true // 控制是否使用默认的 loading,默认值是 true 表示使用默认的 loading
- }
- // 定义拦截器对象
- interceptors = {
- // 请求拦截器
- request: (config) => config,
- // 响应拦截器
- response: (response) => response
- }
- // 定义数组队列,用来存储请求队列、存储请求标识
- queue = []
- // constructor 用于创建和初始化类的属性以及方法
- constructor(params = {}) {
- // 注意:需要传入的参数,覆盖默认的参数,因此传入的参数需要放到最后
- this.defaults = Object.assign({}, this.defaults, params)
- }
- /**
- * @description request 实例方法发送网络请求,接收一个对象类型的参数
- * @param {*} options 属性值和 wx.request() 方法调用时传递的参数保持一致
- * @returns Promise
- */
- request(options) {
- // 如果有新的请求,就清除上一次的定时器
- this.timerId && clearTimeout(this.timerId)
- // 合并完整的请求地址
- options.url = this.defaults.baseURL + options.url
- // 合并请求参数:调用实例方法时传入的覆盖默认的以及实例配置的
- options = {
- ...this.defaults,
- ...options
- }
- // 控制 loading 的显示与隐藏
- if (options.isLoading) {
- this.queue.length === 0 && wx.showLoading({
- mask: true
- })
- this.queue.push('request')
- }
- // 在请求发送之前,调用请求拦截器,新增和修改请求参数
- // 请求拦截器内部,会将新增和修改以后的参数返回
- options = this.interceptors.request(options)
- // 需要使用 Promise 封装 wx.request,处理异步请求
- return new Promise((resolve, reject) => {
- // 如果 method 等于 UPLOAD 说明需要调用 wx.uploadFile() 方法
- // 否则调用的是 wx.request() 方法
- if (options.method === 'UPLOAD') {
- wx.uploadFile({
- ...options,
- success: (res) => {
- // 需要将服务器返回的 JSON 字符串 通过 JSON.parse 转成对象
- res.data = JSON.parse(res.data)
- // 合并参数
- const mergeRes = Object.assign({}, res, {
- config: options,
- isSuccess: true
- })
- resolve(this.interceptors.response(mergeRes, options))
- },
- fail: (err) => {
- // 合并参数
- const mergeErr = Object.assign({}, err, {
- config: options,
- isSuccess: false
- })
- reject(this.interceptors.response(mergeErr, options))
- },
- // 接口调用结束的回调函数(调用成功、失败都会执行)
- complete: () => {
- // 如果需要显示 loading ,那么就需要控制 loading 的隐藏
- if (options.isLoading) {
- // 在每一个请求结束以后,都会执行 complete 回调函数
- // 每次从 queue 队列中删除一个标识
- this.queue.pop()
- // 解决并发请求,loading 闪烁问题
- this.queue.length === 0 && this.queue.push('request')
- //解决并发请求,loading 闪烁问题
- this.timerId = setTimeout(() => {
- this.queue.pop()
- this.queue.length === 0 && wx.hideLoading()
- clearTimeout(this.timerId)
- }, 1)
- }
- }
- })
- } else {
- //console.log(options.url)
- wx.request({
- ...options,
- // 当接口调用成功时会触发 success 回调函数
- success: (res) => {
- // 合并请求参数,方便进行代码调试
- // 追加 isSuccess 属性,是为了标识响应拦截器是 success 调用还是 fail 调用
- const mergeRes = Object.assign({}, res, {
- config: options,
- isSuccess: true
- })
- resolve(this.interceptors.response(mergeRes, options))
- },
- // 当接口调用失败时会触发 fail 回调函数
- fail: (err) => {
- // 合并请求参数,方便进行代码调试
- // 追加 isSuccess 属性,是为了标识响应拦截器是 success 调用还是 fail 调用
- const mergeErr = Object.assign({}, err, {
- config: options,
- isSuccess: false
- })
- reject(this.interceptors.response(mergeErr, options))
- },
- // 接口调用结束的回调函数(调用成功、失败都会执行)
- complete: () => {
- // 如果需要显示 loading ,那么就需要控制 loading 的隐藏
- if (options.isLoading) {
- // 在每一个请求结束以后,都会执行 complete 回调函数
- // 每次从 queue 队列中删除一个标识
- this.queue.pop()
- // 解决并发请求,loading 闪烁问题
- this.queue.length === 0 && this.queue.push('request')
- //解决并发请求,loading 闪烁问题
- this.timerId = setTimeout(() => {
- this.queue.pop()
- this.queue.length === 0 && wx.hideLoading()
- clearTimeout(this.timerId)
- }, 1)
- }
- }
- })
- }
- })
- }
- /**
- * @description 封装 GET 实例方法
- * @param {*} url 请求地址
- * @param {*} data 请求参数
- * @param {*} config 其他请求配置项
- * @returns Promise
- */
- get(url, data = {}, config = {}) {
- // 需要调用 request 请求方法发送请求,只需要组织好参数,传递给 request 请求方法即可
- // 当调用 get 方法时,需要将 request 方法的返回值 return 出去
- return this.request(Object.assign({
- url,
- data,
- method: 'GET'
- }, config))
- }
- /**
- * @description 封装 DELETE 实例方法
- * @param {*} url 请求地址
- * @param {*} data 请求参数
- * @param {*} config 其他请求配置项
- * @returns Promise
- */
- delete(url, data = {}, config = {}) {
- return this.request(Object.assign({
- url,
- data,
- method: 'DELETE'
- }, config))
- }
- /**
- * @description 封装 POST 实例方法
- * @param {*} url 请求地址
- * @param {*} data 请求参数
- * @param {*} config 其他请求配置项
- * @returns Promise
- */
- post(url, data = {}, config = {}) {
- return this.request(Object.assign({
- url,
- data,
- method: 'POST'
- }, config))
- }
- /**
- * @description 封封装 PUT 实例方法
- * @param {*} url 请求地址
- * @param {*} data 请求参数
- * @param {*} config 其他请求配置项
- * @returns Promise
- */
- put(url, data = {}, config = {}) {
- return this.request(Object.assign({
- url,
- data,
- method: 'PUT'
- }, config))
- }
- /**
- * @description 处理并发请求
- * @param {...promise} promise 传入的每一项需要是 Promise
- * @returns Promise
- */
- all(...promise) {
- // 那么展开运算符会将传入的参数转成数组
- return Promise.all(promise)
- }
- /**
- * @description upload 实例方法,用来对 wx.uploadFile 进行封装
- * @param {*} url 文件的上传地址、接口地址
- * @param {*} filePath 要上传的文件资源路径
- * @param {*} name 文件对应的 key
- * @param {*} config 其他配置项
- */
- upload(url, filePath, name = 'file', config = {}) {
- return this.request(
- Object.assign({
- url,
- filePath,
- name,
- method: 'UPLOAD'
- }, config)
- )
- }
- }
- export default WxRequest
|