【笔记】HybridApp中使用Promise化的JS-Bridge
背景:
- 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的更多相关文章
- 锋利的jQuery读书笔记---jQuery中Ajax--序列化元素、Ajax全局事件
serialize()方法: 作用于一个jQuery对象,它能够将DOM元素内容序列化为字符串,用于Ajax请求. <!DOCTYPE html> <html> <hea ...
- 在微信小程序的JS脚本中使用Promise来优化函数处理
在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入 ...
- js中数组扁平化处理
- ES6笔记(7)-- Promise异步编程
系列文章 -- ES6笔记系列 很久很久以前,在做Node.js聊天室,使用MongoDB数据服务的时候就遇到了多重回调嵌套导致代码混乱的问题. JS异步编程有利有弊,Promise的出现,改善了这一 ...
- NodeJs回调操作Promise化
mongoose是一个NodeJs下MongoDB的ORM库.使用这个库,您从DB到表(collection)都不用创建了.只需要在项目中定义好Model. 下面就是用上一篇的代码来演示如何把mong ...
- 彻底理解Javascript 中的 Promise(-------------------------------***---------------------------------)
ES6原生提供了 Promise 对象. 到底是何方妖怪呢?打出来看看: 所谓 Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个 ...
- 深入理解jQuery、Angular、node中的Promise
最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...
- angularJS中的Promise对象($q)的深入理解
原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...
- Javascript中的Promise
Promise定义 Promise是CommonJs的规范之一,包含resolve,reject,done,fail,then等方法,能够帮助我们控制代码的流程,避免函数的多层嵌套.异步在web开发中 ...
随机推荐
- java map遍历、排序,根据value获取key
Map 四种遍历: Map<String,String> map = new HashMap<String, String>(); map.put("one" ...
- javascript排序、功能代码总结[长期更新]
//基本数组去重 ///输入:向数组中添加功能函数unique ///输出:返回一个没有重复元素的数组 Array.prototype.unique = function(){ result =[]; ...
- 用于 SELECT 和 WHERE 子句的函数
一个 SQL 语句中的 select_expression 或 where_definition 可由任何使用了下面所描述函数的表达式组成. 包含 NULL 的表达式总是得出一个 NULL 值结果,除 ...
- NGUI_Font
三.NGUI中的UI字体制作 1.概述: 系统中提供的字体 比较少,而UI字体又是使用最为频繁的,不能因为单一的字体而损失用户量,则这个时候我们就可以通过Font Maker进行字体的制作. 2.动态 ...
- js中, 用变量或对象作为if或其他条件的表达式
源: 因为js是弱语言, 就体现在js的变量是弱类型的, 在js中所有变量类型声明都用var, 而在其他强类型语言中,如java/c,必须有强制类型转换和类型检查才能编译通过等, 但是: 弱语言也有优 ...
- WinSock 异步I/O模型
如果你想在Windows平台上构建服务器应用,那么I/O模型是你必须考虑的. Windows操作系统提供了五种I/O模型,分别是选择(select)模型,异步选择(WSAAsyncSelect)模型, ...
- 21.C++- "++"操作符重载、隐式转换之explicit关键字、类的类型转换函数
++操作符重载 ++操作符分为前置++和后置++,比如: ++a; a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 ...
- 如何打包静态库.a文件 iOS
代码调试好了开始打包成sdk,下面是将要打包的FRSDK代码(FRSDK.h暴露在外面有别人调用) 1.创建新工程(Xcode File-New-Project) 2.把下面的红色框的东西移除 3.将 ...
- webpack----webpack4尝鲜
安装v4.0.0-beta.0 yarn add webpack@next webpack-cli --dev 或者 npm install webpack@next webpack-cli --sa ...
- 【java并发系列】Fork/Join任务(转)
原文链接 当我们需要执行大量的小任务时,有经验的Java开发人员都会采用线程池来高效执行这些小任务.然而,有一种任务,例如,对超过1000万个元素的数组进行排序,这种任务本身可以并发执行,但如何拆解成 ...