1. 程式人生 > >我的 Promise 學習與實踐

我的 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