背景:

  • 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的更多相关文章

  1. 锋利的jQuery读书笔记---jQuery中Ajax--序列化元素、Ajax全局事件

    serialize()方法: 作用于一个jQuery对象,它能够将DOM元素内容序列化为字符串,用于Ajax请求. <!DOCTYPE html> <html> <hea ...

  2. 在微信小程序的JS脚本中使用Promise来优化函数处理

    在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入 ...

  3. js中数组扁平化处理

  4. ES6笔记(7)-- Promise异步编程

    系列文章 -- ES6笔记系列 很久很久以前,在做Node.js聊天室,使用MongoDB数据服务的时候就遇到了多重回调嵌套导致代码混乱的问题. JS异步编程有利有弊,Promise的出现,改善了这一 ...

  5. NodeJs回调操作Promise化

    mongoose是一个NodeJs下MongoDB的ORM库.使用这个库,您从DB到表(collection)都不用创建了.只需要在项目中定义好Model. 下面就是用上一篇的代码来演示如何把mong ...

  6. 彻底理解Javascript 中的 Promise(-------------------------------***---------------------------------)

    ES6原生提供了 Promise 对象. 到底是何方妖怪呢?打出来看看: 所谓 Promise,就是一个对象,用来传递异步操作的消息.它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个 ...

  7. 深入理解jQuery、Angular、node中的Promise

    最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...

  8. angularJS中的Promise对象($q)的深入理解

    原文链接:a better way to learn AngularJS - promises AngularJS通过内置的$q服务提供Promise编程模式.通过将异步函数注册到promise对象, ...

  9. Javascript中的Promise

    Promise定义 Promise是CommonJs的规范之一,包含resolve,reject,done,fail,then等方法,能够帮助我们控制代码的流程,避免函数的多层嵌套.异步在web开发中 ...

随机推荐

  1. Win7硬盘的AHCI模式

    1.什么是硬盘的AHCI模式? AHCI是串行ATA高级主控接口的英文缩写,它是Intel所主导的一项技术,它允许存储驱动程序启用高级SATA功能,如本机命令队列(NCQ)和热插拔.开启AHCI之后可 ...

  2. Ubuntu上安装VMware tools

    Ubuntu上安装VMware tools author:headsen chen     2017-10-12  -  10:13:50 个人原创,转载请注明作者,出处,否则.依法追究法律责任 ch ...

  3. 【前端单元测试入门05】react的单元测试之jest

    jest jest是facebook推出的一款测试框架,集成了前面所讲的Mocha和chai,jsdom,sinon等功能. 安装 npm install --save-dev jest npm in ...

  4. C语言第十次博客作业--结构体

    一.PTA实验作业 题目1: 结构体数组按总分排序 1. 本题PTA提交列表 2. 设计思路 求出每名学生的总分 定义i,j循环变量 for i=0 to n for j=0 to 3 p[i].su ...

  5. 设计模式之观察者(OBSERVER)模式

    定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.  Observer模式描述了如何建立这种关系.这一模式中的关键对象是目标(subject ...

  6. 第六届蓝桥杯B组java最后一题

    10.压缩变换(程序设计) 小明最近在研究压缩算法. 他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比. 然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些 ...

  7. Linux快速搭建FTP服务器

    FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为"文传协议".用于Internet上的控制文件的双向传输.同时,它也是一个应用程序(A ...

  8. Python十题(第2课)

    一.天天向上的力量 C 一年365天,以第1天的能力值为基数,记为1.0.当好好学习时,能力值相比前一天提高N‰:当没有学习时,由于遗忘等原因能力值相比前一天下降N‰.每天努力或放任,一年下来的能力值 ...

  9. Oracle修改字段类型方法小技巧

    有一个表名为tb,字段段名为name,数据类型nchar(20). 1.假设字段数据为空,则不管改为什么字段类型,可以直接执行:alter table tb modify (name nvarchar ...

  10. node初始

    ### 一.什么是node.js > Node是一个基于 Chrome V8 引擎的 JavaScript 运行环境 > > Node使用了一个事件驱动.非阻塞式 I/O 的模型,使 ...