我的 Promise 學習與實踐
推薦思路:瞭解 Promise —> 試寫 Promise 小例子,將原來的回撥函式改為 Promise 形式 —> 專案中實踐。
推薦 2 位大神的文章:
阮一峰:https://www.imooc.com/article/20580?block_id=tuijian_wz
廖雪峰:廖雪峰官網
讀完其一必能對 Promise 有個原理性和功能性瞭解,其中還包括了很多 demo。
我在小程式開發中使用 Promise 時,在 .then() 中出錯,後來輾轉一週,發現是少了個 return,案例如下:
這是我小程式 util.js 封裝的請求函式
TC._postAjaxPro = function (url, params) { return new Promise((resolve, reject) => { wx.showLoading({ title: '載入中', mask: true }) wx.request({ url: TC._url + url, data: params, method: 'POST', header: { 'content-type': 'application/x-www-form-urlencoded' }, success: (res) => { console.log(res) if (res.data.Code == 0 || res.data.code == 0 || res.Code == 0 || res.code == 0) { resolve(res.data) } else { TC._toast(res.data.Msg || res.data.msg || res.Msg || res.msg, 'none') reject(res.data) } }, complete: (res) => { setTimeout(() => { wx.hideLoading() }, 400) } }) }) }
這是我小程式詳情頁的請求函式,呼叫了上文 util.js 中的函式
寫法一:promise.then()
sendMsg() { let that = this; wx.showModal({ title: '提示', content: '訂單完成,需要傳送簡訊給客戶嗎?', success: (res) => { if (res.confirm) { let param = { OrderId: that.data.OrderId, Finish: that.data.detailData.Finish } util.TC._postAjaxPro('AirPortService/AirPortService.aspx', { UserId: wx.getStorageSync('LOGIN_DATA').UserId, ComId: wx.getStorageSync('LOGIN_DATA').ComId, Action: 'SetOrderFinish', Param: JSON.stringify(param) }) .then((resolve) => { let param2 = { OrderId: that.data.OrderId } return util.TC._postAjaxPro('AirPortService/AirPortService.aspx', { UserId: wx.getStorageSync('LOGIN_DATA').UserId, ComId: wx.getStorageSync('LOGIN_DATA').ComId, Action: 'SendFinishSms', Param: JSON.stringify(param2) }) }) .then((resolve) => { util.TC._toast(resolve.Msg, 'success', 800); }) } } }) },
當時,第一個 .then() 中的 return 沒寫,發現在第一個 .then() 中 console.log(resolve) 時結果正常顯示;而第二個 .then() 中的 console.log(resolve) 時結果為 undefined。這是為什麼?
then方法可以接受 2 個回撥函式作為引數,第一個回撥函式是promise物件的狀態變為resolved時呼叫,第二個回撥函式是promise物件的狀態變為rejected時呼叫。其中,第二個函式是可選的,不一定要提供,這兩個函式都接受promise物件傳出的值作為引數。 根據這個解釋,第一個 .then() 中的引數就是 promise 執行後的結果,作為其引數。而第二個 .then() 中的函式執行完後,執行的結果如果並未 return,此時在外層續用 .then(),就沒有結果作為其引數,所以如果這麼寫就必須 return 上一個 .then() 中的執行結果。
在此有一點很有意思的地方,如果把第一個 .then() 中不 return 執行結果,第二個 .then() 寫在第一個 .then() 中,也是可以執行的(目測正常,但這又變成回撥地獄了),程式碼如下:
.then((resolve) => {
let param2 = {
OrderId: that.data.OrderId
}
util.TC._postAjaxPro('AirPortService/AirPortService.aspx', {
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SendFinishSms',
Param: JSON.stringify(param2)
})
.then((resolve) => {
util.TC._toast(resolve.Msg, 'success', 800);
})
})
從以上程式碼可以看出,Promise 就是把每一次回撥的結果都 return 出來,作為 .then() 的引數,成為鏈式操作的。
寫法二:async await
sendMsg() {
let that = this;
wx.showModal({
title: '提示',
content: '訂單完成,需要傳送簡訊給客戶嗎?',
async success(res) {
if (res.confirm) {
let param1 = {
OrderId: that.data.OrderId,
Finish: that.data.detailData.Finish
}
let firstRes = await util.TC._postAjaxPro(
'AirPortService/AirPortService.aspx',
{
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SetOrderFinish',
Param: JSON.stringify(param1)
}
)
let param2 = {
OrderId: that.data.OrderId
}
let secondRes = await util.TC._postAjaxPro(
'AirPortService/AirPortService.aspx',
{
UserId: wx.getStorageSync('LOGIN_DATA').UserId,
ComId: wx.getStorageSync('LOGIN_DATA').ComId,
Action: 'SendFinishSms',
Param: JSON.stringify(param2)
}
)
util.TC._toast(secondRes.Msg, 'success', 800);
}
}
})
}
以上程式碼就是一點經驗,如有同行小夥伴發現不合理之處,還望留言指教。路漫漫其修遠兮,我們一起去求索0.0