Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強大。
Promise對象有以下兩個特點:
(1)對象的狀態(tài)不受外界影響。Promise對象代表一個異步操作,有三種狀態(tài):pending(進行中)、fulfilled(已成功)和rejected(已失?。?。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。
(2)一旦狀態(tài)改變,就不會再變,任何時候都可以得到這個結(jié)果。Promise對象的狀態(tài)改變,只有兩種可能:從pending變?yōu)閒ulfilled和從pending變?yōu)閞ejected。只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會再變了,會一直保持這個結(jié)果,這時就稱為 resolved(已定型)。如果改變已經(jīng)發(fā)生了,你再對Promise對象添加回調(diào)函數(shù),也會立即得到這個結(jié)果。這與事件(Event)完全不同,事件的特點是,如果你錯過了它,再去監(jiān)聽,是得不到結(jié)果的。
缺點:
Promise也有一些缺點。首先,無法取消Promise,一旦新建它就會立即執(zhí)行,無法中途取消。其次,如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯誤,不會反應(yīng)到外部。第三,當(dāng)處于pending狀態(tài)時,無法得知目前進展到哪一個階段(剛剛開始還是即將完成)。
一、在utils文件夾下創(chuàng)建一個tools.js,代碼如下:
/**
* 工具類
*/
// 服務(wù)器地址
const hostApi = ''
/**
* @封裝http請求方法
* @params 形參,是一個對象
* {
* url: '', //接口,必傳
* method: '', //方法,默認(rèn)為GET,可選
* data: '' //數(shù)據(jù),可選
* }
*/
const http = (params) => {
// 返回Primise對象
return new Promise((resolve, reject) => {
wx.showLoading({
title: '加載中',
mask: true
})
let method = params.method || 'GET'
const SUCCESS_STATUS = 200
wx.request({
url: hostApi + params.url,
method: method,
data: params.data || {},
header: {
'content-type': Object.is(method, 'GET') ? 'application/json' : 'application/x-www-form-urlencoded'
},
success: res => {
if (Object.is(res.statusCode, SUCCESS_STATUS)) {
wx.hideLoading()
resolve(res.data)
}
},
fail: err => {
wx.hideLoading()
showError()
reject(err)
}
})
})
}
/**
* 彈窗提示網(wǎng)絡(luò)錯誤
*/
function showError() {
wx.showToast({
title: '加載失敗',
icon: 'none',
duration: 2000,
mask: true
})
}
module.exports = {
http
}
2、在小程序app.js里配置全局函數(shù)
//app.js
const req = require('/utils/tools.js') //引入創(chuàng)建的tools.js文件
App({
onLaunch: function () {
// 展示本地存儲能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登錄
wx.login({
success: res => {
// 發(fā)送 res.code 到后臺換取 openId, sessionKey, unionId
}
})
// 獲取用戶信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已經(jīng)授權(quán),可以直接調(diào)用 getUserInfo 獲取頭像昵稱,不會彈框
wx.getUserInfo({
success: res => {
// 可以將 res 發(fā)送給后臺解碼出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是網(wǎng)絡(luò)請求,可能會在 Page.onLoad 之后才返回
// 所以此處加入 callback 以防止這種情況
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
globalData: {
userInfo: null
},
api: { //封裝接口
},
http: { //配置全局變量
req: req.http
}
})
3、在項目代碼中調(diào)用方法
app.http.req(params).then(res => {
//返回結(jié)果的處理邏輯
console.log(res)
...
})