最近在寫微信小程序,爲了能用上 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 => {});