1. 程式人生 > >【筆記】HybridApp中使用Promise化的JS-Bridge

【筆記】HybridApp中使用Promise化的JS-Bridge

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