回调地狱一向是影响开发和维护的症结所在,无数个success()
的嵌套再嵌套,导致代码层级颇深,盘一次逻辑都要费劲千辛万苦,ES6语法中的Promise
,便是专为解决JS中异步请求回调的信任问题而存在的,结合小程序目前提供的API支持,可以用Promise
将其进行简单封装,优化性能体验。具体代码如下(注意看注释):
1. 首先在公共的util.js
(或者自己创建的公有JS文件)中加入如下方法:
/**
* wxPromisify 使用promise封装request请求
* @fn 传入的函数,如wx.request、wx.download
*/
function wxPromisify(fn) {
return function(obj = {}) {
return new Promise((resolve, reject) => {
obj.success = function(res) { //网络通畅,请求发送成功
console.log(res)
if (res.data.code == 200) { //判断后台返回的状态码,若是成功,返回resolve()
return resolve(res)
} else { //若是返回错误的状态码,弹窗提示失败信息,并附带错误代码,以便快速定位问题所在
wx.showModal({
title: res.data.msg,
content: "错误码:" + res.data.code,
showCancel: false,
})
}
}
obj.fail = function(res) { //网络阻塞,请求发送失败,显示错误提示
showError() //此函数在下面定义,用于打印错误信息
return reject(res)
}
fn(obj) //执行函数,obj为传入函数的参数
})
}
}
/**
* 加载超时后显示网络错误提示
* 当前设置为等待2.5秒,若超时后仍未返回请求结果,弹窗提示网络错误
* @param 传入一个Promise对象
*/
function racePromise(proRequest){
return Promise.race([
proRequest,
new Promise(function (resolve, reject) {
setTimeout(() => reject(), 2500)
})
])
}
/**
* 弹窗提示网络错误
*/
function showError(){
wx.showModal({
title: '加载失败',
content: '请检查网络连接',
showCancel: false,
})
}
最后将方法导出:
module.exports = {
URL: "https://...", //具体的请求地址头
wxPromisify: wxPromisify,
racePromise: racePromise,
showError: showError,
}
2. 在wxml中进行调用,首先在Page
上方引入util.js
文件,并封装部分方法:
const util = require('../../utils/util.js')
//调用util.js里写好的方法,将小程序原生的request方法包装成一个Promise对象
//这里也可以传入其他原生请求,如wx.getSystemInfo、wx.getUserInfo、wx.login等,但需要将util.js里的‘判断状态码’这一步删掉
const proRequest = util.wxPromisify(wx.request)
然后在方法里进行调用,发送请求:
/**
* 通过code获取用户openid
*/
getOpenid(code) {
var that = this; //个人习惯,为避免this指向出错,函数前必加
util.racePromise(proRequest({
url: util.URL + "...?code=" + code, //请求地址
method: 'POST', //函数方法
})).then(res => { //!!!注意括号的个数!!!
/* ... */ //若是请求成功,执行后续处理和操作 res是请求响应的结果
}).catch(res => { //若是请求超时,则catch进行捕获,弹窗提示网络错误
util.showError()
})
},
以上便是简单的封装方法,并处理了基本错误,后续可以根据需求添加Promise.all
等方法,完善业务逻辑。
如有不妥之处,万望指正!