??回調(diào)地獄一向是影響開發(fā)和維護(hù)的癥結(jié)所在找田,無(wú)數(shù)個(gè)success()
的嵌套再嵌套彬呻,導(dǎo)致代碼層級(jí)頗深,盤一次邏輯都要費(fèi)勁千辛萬(wàn)苦解阅,ES6語(yǔ)法中的Promise
落竹,便是專為解決JS中異步請(qǐng)求回調(diào)的信任問(wèn)題而存在的,結(jié)合小程序目前提供的API支持货抄,可以用Promise
將其進(jìn)行簡(jiǎn)單封裝述召,優(yōu)化性能體驗(yàn)。具體代碼如下(注意看注釋):
??1. 首先在公共的util.js
(或者自己創(chuàng)建的公有JS文件)中加入如下方法:
/**
* wxPromisify 使用promise封裝request請(qǐng)求
* @fn 傳入的函數(shù)蟹地,如wx.request积暖、wx.download
*/
function wxPromisify(fn) {
return function(obj = {}) {
return new Promise((resolve, reject) => {
obj.success = function(res) { //網(wǎng)絡(luò)通暢,請(qǐng)求發(fā)送成功
console.log(res)
if (res.data.code == 200) { //判斷后臺(tái)返回的狀態(tài)碼怪与,若是成功夺刑,返回resolve()
return resolve(res)
} else { //若是返回錯(cuò)誤的狀態(tài)碼,彈窗提示失敗信息分别,并附帶錯(cuò)誤代碼遍愿,以便快速定位問(wèn)題所在
wx.showModal({
title: res.data.msg,
content: "錯(cuò)誤碼:" + res.data.code,
showCancel: false,
})
}
}
obj.fail = function(res) { //網(wǎng)絡(luò)阻塞,請(qǐng)求發(fā)送失敗茎杂,顯示錯(cuò)誤提示
showError() //此函數(shù)在下面定義错览,用于打印錯(cuò)誤信息
return reject(res)
}
fn(obj) //執(zhí)行函數(shù),obj為傳入函數(shù)的參數(shù)
})
}
}
/**
* 加載超時(shí)后顯示網(wǎng)絡(luò)錯(cuò)誤提示
* 當(dāng)前設(shè)置為等待2.5秒煌往,若超時(shí)后仍未返回請(qǐng)求結(jié)果倾哺,彈窗提示網(wǎng)絡(luò)錯(cuò)誤
* @param 傳入一個(gè)Promise對(duì)象
*/
function racePromise(proRequest){
return Promise.race([
proRequest,
new Promise(function (resolve, reject) {
setTimeout(() => reject(), 2500)
})
])
}
/**
* 彈窗提示網(wǎng)絡(luò)錯(cuò)誤
*/
function showError(){
wx.showModal({
title: '加載失敗',
content: '請(qǐng)檢查網(wǎng)絡(luò)連接',
showCancel: false,
})
}
??最后將方法導(dǎo)出:
module.exports = {
URL: "https://...", //具體的請(qǐng)求地址頭
wxPromisify: wxPromisify,
racePromise: racePromise,
showError: showError,
}
??2. 在wxml中進(jìn)行調(diào)用轧邪,首先在Page
上方引入util.js
文件,并封裝部分方法:
const util = require('../../utils/util.js')
//調(diào)用util.js里寫好的方法羞海,將小程序原生的request方法包裝成一個(gè)Promise對(duì)象
//這里也可以傳入其他原生請(qǐng)求忌愚,如wx.getSystemInfo、wx.getUserInfo却邓、wx.login等硕糊,但需要將util.js里的‘判斷狀態(tài)碼’這一步刪掉
const proRequest = util.wxPromisify(wx.request)
??然后在方法里進(jìn)行調(diào)用,發(fā)送請(qǐng)求:
/**
* 通過(guò)code獲取用戶openid
*/
getOpenid(code) {
var that = this; //個(gè)人習(xí)慣腊徙,為避免this指向出錯(cuò)简十,函數(shù)前必加
util.racePromise(proRequest({
url: util.URL + "...?code=" + code, //請(qǐng)求地址
method: 'POST', //函數(shù)方法
})).then(res => { //!G颂凇螟蝙!注意括號(hào)的個(gè)數(shù)!C裆怠胰默!
/* ... */ //若是請(qǐng)求成功,執(zhí)行后續(xù)處理和操作 res是請(qǐng)求響應(yīng)的結(jié)果
}).catch(res => { //若是請(qǐng)求超時(shí)漓踢,則catch進(jìn)行捕獲牵署,彈窗提示網(wǎng)絡(luò)錯(cuò)誤
util.showError()
})
},
??以上便是簡(jiǎn)單的封裝方法,并處理了基本錯(cuò)誤喧半,后續(xù)可以根據(jù)需求添加Promise.all
等方法奴迅,完善業(yè)務(wù)邏輯。
??如有不妥之處薯酝,萬(wàn)望指正半沽!