小程序封装网络请求

264 阅读3分钟

在项目中,我们的请求大多数都是把请求用Promise封装一下,为什么要封装请求呢,这样又有什么好处呢
我们先来看一段代码

在这里插入图片描述

看一下打印结果,testFun方法里面的userInfo是一个空数组,为什么会这样呢

因为小程序的网络请求是一个异步的请求,所以数据请求的同时,可以继续向下执行函数,所以在onLoad中请求到数据的同时还可以继续的向下执行testFun函数里面的代码

正因为小程序里面的请求是一个异步的,所以我们也不能这样

let res = wx.request({
    url: xxxx,
    method: 'get'
})

这时候该怎么解决呢

1、在成功回调里面调用testFun方法

在这里插入图片描述

这种方法对于简单的逻辑处理还可以,但是要有很多层异步,就要嵌套很多层不仅写起来麻烦,脑子都快要炸了,就像下面这样(只是描述一下类似这种情况),这样不仅写起来费死劲,代码可读性和可维护性也很差,这个时候我们就要用到Promise来解决这个问题了,用Promise的话我们就可以使用他的链式调用,不太了解的可以看一下这篇文章:Promise对象

test().then(test1()).then(test2()).then(.....)

在这里插入图片描述

2、使用Promise

我们可以使用Promise来对小程序的请求进行简单的封装,小程序的请求把参数放在一个对象里面了,所以我封装的时候把参数也都封装称从外部传来的,因为项目中请求的地方用到的非常多,直接封装成全局的一个js文件,然后引入会比较好

在这里的时候我们还可以调用微信的wx.getNetWorkType这个api来获取网络状态,有网络的话再resolve

class Util {
  static httpRequest(options) {
    let tAccessToken = wx.getStorageSync("access_token");
    let tHeader = Object.assign({
      "Authorization": 'Bearer ' + tAccessToken
    }, options.header)
    return new Promise((resolve, reject) => {
      wx.request({
        url: options.url,
        header: tHeader,
        method: options.method || "GET",
        data: options.data || {},
        success(res) {
          resolve(res)
        },
        fail(err) {
          reject(err)
        },
        complete(finish) {
          resolve(finish)
        }
      })
    })
  }
}

module.exports = Util

在需要请求地方先引入js文件,然后直接调用方法即可

const Util = require('../../utils/util.js')


Util.httpRequest({
   url: `https://xxx.com/xxx`,
   data: {
   	 a: xxx,
  	 b: xxx
   },
   method: 'post',
   //header可以不加,在封装的时候默认已经加上了,按照个人实际情况
   header: {
     "Authorization": 'Bearer ' + access_token
   }
}).then((res) => {
	console.log(res)
}).catch((err) => {
	console.log(errr)
})

在这里插入图片描述

有的时候太多的链式调用看的也会很不舒服。而且有可能出点链式地狱,这个时候推荐用es8中的 async、await

async

带async关键字的函数,是声明异步函数,返回值是promise对象,如果async关键字函数返回的不是promise,会自动用Promise.resolve()包装

await

1、await等待右侧表达式的结果,这个结果是promise对象或者其他值。

2、如果它等到的不是一个 promise 对象,那 await 表达式的运算结果就是它等到的东西。

3、如果它等到的是一个 promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果

async fun(){
    let { data: { data, flag, code, message } } = await Util.httpRequest({
      url: `https:xxx.com/xxxx`,
      method: 'get',
      data: {
        a: xxx
      }
    })
    if(code === 后台返回的固定值){
      this.setData({
        ccc: xxxx
      })
    } else {
      wx.showToast({
        title: message || '获取数据失败',
      })
    }
  },

注意:

1、千万不要用try、catch来抓取catch错误,因为会在promise内部给消化掉,而且,不用async、await那么try、catch也用不了 的,try、catch只能监听同步的函数

2、要想抓到异步函数的错误,就要封装成Promise.reject,然后用async、await抓取,这样子try、catch才有用;而且异步函数有 catch了,也没啥必要再用try、catch,错误的监听一个其实就已经够

在这里插入图片描述

在这里插入图片描述

避免有下面这种写法

async fun(){
    try {
      let { data: { data, code, message } } = await Util.httpRequest({
        url: `${hostCharge}/restaurant/currentOrderWx`,
        method: 'get',
        header: {
          "Authorization": 'Bearer ' + token
        },
        data: {
          userId: userId,
          companyId: companyId
        }
      })
      if(code === 20000){
        
      } else {
        wx.showToast({
          title: message,
        })
      }
    } catch (error) {
      console.log(error)
    }
  },