在项目中,我们的请求大多数都是把请求用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)
}
},