小程序接口的 promise 化。

最近在寫微信小程序,爲了能用上 async/await 方法,須要把微信提供的異步操做包裝成 Promise 對象,爲此寫了一個簡單的 promise(fie) 函數:javascript

/**
 * @function promise - 將 wx 接口 promise 化
 * 
 * @param { String|Function } wxApi - 須要轉換的接口/接口名
 * @param { Object|Any } [originParam = {}] - 原接口要求的參數對象
 * @param { Object|Any } [extra] - 接口要求的其餘參數
 */
function promise(wxApi, originParam = {}, extra){
  const api = wxApi instanceof Function?
    wxApi:
    wx[wxApi];

  return new Promise((done, fail) =>
    api({
      ...originParam,
      {
        success: done,
        failed: fail
      }
    },
    extra)
  );
}

正當我沾沾自喜、興致沖沖地調用拍照接口測試時,控制檯扔給我一個 「this._invokeMethod is not a Function」 的錯誤。顯而易見,因爲 wxApi 被當作參數傳遞,執行時的 this 與預期不一致,所以須要顯式指定 this ,遂把函數再改改:java

/**
 * @function promise - 將 wx 接口 promise 化
 * 
 * @param { String|Function } wxApi - 須要轉換的接口/接口名
 * @param { Object|Any } [originParam = {}] - 原接口要求的參數對象
 * @param { Object|Any } [context = wx] -  執行上下文
 * @param { Object|Any } [extra] - 接口要求的其餘參數
 */
function promise(wxApi, originParam = {}, context = wx, extra){
  const api = wxApi instanceof Function?
    wxApi:
    context[wxApi];

  return new Promise((done, fail) =>
    api.call({
      ...originParam,
      {
        success: done,
        failed: fail
      }
    },
    extra)
  );
}

因爲大部分接口都是 wx 的方法,而這些方法的調用參數格式大體相同,所以這個 promise 方法在大多數狀況下仍是比較省事的,使用默認參數的狀況下,只需傳入對應方法的名稱。好比調用 wx.getUserInfo :小程序

promise('getUserInfo').then(e => {});
// 等價於:
wx.getUserInfo({
    success: e => {}
})

不過拍照接口是 cameraContext 的方法,因此傳遞的是 createCameraContext 方法的返回值,這種略複雜的接口最好在 promise 的基礎上進行二次封裝:微信小程序

/**
 * @function takePhoto - promise風格的拍照接口
 * 
 * @param  { Object|Any } [options = {}] - 相機配置
 * 
 * @return {Promise}
 */
export function takePhoto(options = {}){
    const tempOptions = {
        quality: 'high',
        ...options
    }

  const cameraContext = createCameraContext();

  return promise(cameraContext.takePhoto, tempOptions, cameraContext);
}

// 調用的時候(使用默認配置)
takePhoto().then(e => {});
相關文章
相關標籤/搜索