微信小程序和服务器端的数据交互是通过wx.request()这个API函数来完成的,这是一个异步函数。
在有些情况下,我们需要根据服务器传递回来的值来做下一个操作的时候,其代码都要写到success:function(res){ }函数中。
如果success:function(res){ } 中又要调用wx.request(),就会碰到所谓的“回调地狱”,难以编码和维护。
wx.request()还不支持Promise这种方式,也就是说不能用wx.request().then()的方式来处理数据,所以我们需要用Promise对wx.request()来做封装。
使用Promise分两步:
一 、先构造 Promise 对象,语法如下,Promise的构造函数用匿名函数 function(resolve, reject){ } 做参数,
匿名函数的 resolve 和 reject 参数是执行成功和失败时要调用的函数:
let pro = new Promise(function(resolve, reject) {
//do something.
});
二、然后在then方法中传入要回调的函数做下一步的处理,如下:
pro.then(resolve, reject);
将其应用到wx.request()上,即
let baseOptions = (params, method = 'GET')=>{
let { url, data } = params
let contentType = 'application/x-www-form-urlencoded'
contentType = params.contentType || contentType
let pro = new Promise(function(resolve, reject) {
wx.request({
isShowLoading: true,
loadingText: '正在加载',
url: base + url,
data: data,
method: method,
header: {
'content-type': contentType,
'Authorization': wx.getStorageSync('token')
},
success(res) {
if (res.statusCode === HTTP_STATUS.NOT_FOUND) {
reject('请求资源不存在')
} else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) {
reject('服务端出现了问题')
} else if (res.statusCode === HTTP_STATUS.FORBIDDEN) {
reject('没有权限访问')
} else if (res.statusCode === HTTP_STATUS.SUCCESS) {
if (res.data.code === HTTP_STATUS.TOKEN_EXPIRE) {
wx.clearStorageSync()
wx.reLaunch({
url:'/pages/index/index'
})
wx.showToast({
title: '登录状态过期,请重新登录',
icon:'none',
duration: 2000
})
}else if(res.data.code === HTTP_STATUS.AUTHENTICATE){
wx.clearStorageSync()
wx.reLaunch({
url:'/pages/index/index'
})
wx.showToast({
title: '认证失败,请重新登录',
icon:'none',
duration: 2000
})
}
else {
if(res.header.Authorization){
wx.setStorageSync('token',res.header.Authorization)
}
resolve(res.data)
}
}
},
fail(error) {
console.error(error)
if(error.errMsg === 'request:fail timeout'){
error.errMsg = '请求超时'
}
},
error(e) {
console.error('api', '请求接口出现问题', e)
}
})
})
return pro
}
export let get = (url, data = '')=>{
let option = { url, data }
return baseOptions(option)
}
export let post = function (url, data, contentType) {
let params = { url, data, contentType }
return baseOptions(params, 'POST')
}
调用代码为:
getUserInfoByOpenId() {
const openId = wx.getStorageSync('openid')
get('/sysuser/getUserInfoByOpenId',{openId:openId}).then(
res => {
if(res.code === 200){
this.setData({
userInfo: res.data
})
}else {
wx.showToast({
title: res.message,
icon: 'none',
duration: 2000
})
}
}
).catch((e) => {
wx.showToast({
title: e.errMsg,
icon: 'none',
duration: 2000
})
})
}
即相当于可使用wx.request().then()了。