【筆記】HybridApp中使用Promise化的JS-Bridge
阿新 • • 發佈:2018-04-09
fine 獲取 nbsp ted reat AS all turn 方法
背景:
- HybridApp,前端采用JS-bridge的方式調用Native的接口,如獲取設備信息、拍照、人臉識別等
- 前端封裝了調用庫,每次調用Native接口,需要進行兩步操作(1、在window下掛載Native回調函數;2、調用InvokeNative函數,發送請求數據)
改造前:
使用回調,在每次調用Ygritte中的方法前,必須先定義好回調函數,掛載在window[funcName]上。然後調用。
問題:
1、可能導致回調地獄:比如某個場景中,需要先判斷App版本,然後調用不同的Native接口,那麽就需要在回調中再次定義回調,產生嵌套;
2、無法改為同步:比如上圖的場景中,在進入Home頁面,在 [created] 中需要判斷App版本,如果版本過低,在 [mounted] 中需要提示。使用回調的方式,理論上存在mounted執行時, [created] 中的回調還沒有執行。
改造:
- 使用Promise對調用和回調進行改造
- 為保證舊代碼兼容,不修改原來在Ygritte中使用原型中添加接口的形式
- 回調函數的定義封裝,在回調中執行resolve
/** * 獲得用戶簽名數據 * @param {Float} lineWidth 如"1.5",傳0或者null則視為使用native默認值 * @param {String} lineColor 畫筆顏色值的字符串,不帶#號,如:"666666",傳空字符串或null則視為使用native默認值 * @param {String} callbackName 回調手寫簽名的圖片,原圖、背景透明、為base64編碼的字符串,key為"signatureImage";如果用戶取消,則回調空json * @version: from app version 2.4.0*/ Ygritte.prototype.getHandWritingSignature = function(lineWidth, lineColor, callbackName){ var args = [‘knowNothing‘, ‘getHandWritingSignature‘, callbackName || ‘‘, { lineWidth: lineWidth, lineColor: lineColor }]; snow.invokeNative(args); };
不修改上方原有的函數,新增下方函數封裝
/** * 校驗App返回值,避免多次回調,只執行一個resolve的問題 * Promise的定義中一旦resolve或者reject,就不會執行後面的resolve和reject * * getPhoto: 成功獲取圖片數據時,會回調兩次,一次參數為圖片值,一次參數為undefined * * @param {string} method * @param {object} res * @returns*/ function checkNativeReturn(method, res) { if (method === ‘getPhoto‘ && (!res || ‘{}‘ === JSON.stringify(res))) return false; return true; } /** * Promise化的方法調用 * * 白靈(Ghost)是瓊恩·雪諾 的白色冰原狼 ,外觀像狐貍。它的毛色凈白,眼瞳紅如鮮血。 * * @param {object} { method, key = method, data } * @returns */ function Ghost({ method, key = method, data }) { return new Promise((resolve, reject) => { if (Ygritte[method] && typeof(Ygritte[method]) === ‘function‘) { // 全局掛載App回調函數 window[key] = (res) => { if (checkNativeReturn(method, res)){ resolve(res); window[key] = () => {}; } else { reject(res); } }; var args = [‘knowNothing‘, method, key || ‘‘, data]; snow.invokeNative(args); } else { reject(new Error(‘不存在的Native方法,請檢查method‘)); } }); }
改造後:
1、使用promise封裝,避免在業務代碼中出現在全局掛載函數的行為
2、可以使用async語法,代碼表意更清晰
遺留:
1、部分Native接口調用後,會執行兩次回調,原來是在業務代碼中進行判斷。Promise化後需要用代碼磨平,因為Promise中resolve函數只會執行一次,無法保證第一次執行的是業務需要的參數。
【筆記】HybridApp中使用Promise化的JS-Bridge