如何把 Callback 接口包装成 Promise 接口
最近一段时间一直在看Node.js,在开发过程中经常要调用一些异步接口,通常在接口的最后一个参数会传入一个回调函数,可以用来处理异常,非异常情况。大致模式如下:
var fs = require(“fs");
fs.readFile(filename, "binary", function(err, file){
if(err){
//异常情况
}else{
//正常情况
}
});
但是,这种写法遇上比较复杂的逻辑时,就很容易出现 callback hell的问题。
Node.js需要按顺序执行异步逻辑时一般采用后续传递风格,也就是将后续逻辑封装在回调函数中作为起始函数的参数,逐层嵌套。这种风格虽然可以提高 CPU利用率,降低等待时间,但当后续逻辑步骤较多时会影响代码的可读性,结果代码的修改维护变得很困难。根据这种代码的样子,一般称其 为"callback hell"
对异步接口的处理方式都是依赖于Promise,对于上篇文章讲到的Fetch,直接返回Promise.
如何将callback接口变成Promise接口?
var promisify = function promisify(fn, receiver) {
return function() {
for(var _len = argument.length, args = Array(_len), _key = 0; _key<_len; _key++) {
args[_key] = arguments[_key];
} return new Promise(function (resolve, reject) {
fn.apply(receiver, [].concat(args,[function(err, res){
return err ? reject(err) : resolve(res);
}]));
});
};
};
通过 promisify这个函数,就可以把接口进行转换。
上面的模板就可以改成下面的形式:
var fs = require("fs");
var readFilePromise = promisify(fs.readFile, fs); //包装为Promise接口
readFilePromise(filename, "binary").then(function(file){
//正常情况
}).catch(function(err){
//异常情况
})
特殊情况
有些设计不合理的接口可能会传递多个值给回调函数,如:
var fn = function(foo, callback){
if(success){
callback(null, file1, file2);
}else{
callback(err);
}
}
很明显 这个接口传了 file1,file2两个值,是没有办法用上述方法的,用了上述接口转换没有办法获取到file2的数据。
对于这种情况只能手工包装。
提高性能
可以使用高性能的Promise库来提高性能。如:bluebird。简单对比测试发现,blurbird 的性能是 V8 里内置的 Promise 3 倍左右.
替换内置的Promise:
- global.Promise = require("bluebird");
如果项目里用了 Babel 编译 ES6 代码的话,可以用下面的方式替换:如果项目里用了 Babel 编译 ES6 代码的话,可以用下面的方式替换:
- require("babel-runtime/core-js/promise").default = require("bluebird");
- global.Promise = require("bluebird");
Babel 用于转化你的 JavaScript 代码
你的 JavaScript 代码是这样的:
myJavaScript("foobar");
转化之后的 JavaScript 是这样的
myNewTransformedJavaScript("yay!");
原文地址:http://welefen.com/post/how-to-convert-callback-to-promise.html
如何把 Callback 接口包装成 Promise 接口的更多相关文章
- 把ajax包装成promise的形式(2)
概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...
- 把ajax包装成promise的形式(3)
概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...
- 把ajax包装成promise的形式(1)
概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...
- 使用SWIG将C++接口转换成Java接口
PS:此文章仅作为个人记录使用,代码属于私密,故无法公开: 以C++类classifier为例,文件保存于百度网盘 https://pan.baidu.com/s/1c2AwhaS(需密码) 系统:U ...
- SIP:用Riverbank的SIP创建C++库的Python模块(把自己的C++库包装成Python模块)
我们发现PyQt做的Python版的PyQt是如此好用,如果想把自己的C++库包装成Python模块该如何实现呢? 这里介绍下用SIP包装C++库时值得参考的功能实现: 需要Python模块中实现C+ ...
- Go part 6 接口,接口排序,接口嵌套组合,接口与类型转换,接口断言
接口 接口是一种协议,比如一个汽车的协议,就应该有 “行驶”,“按喇叭”,“开远光” 等功能(方法),这就是实现汽车的协议规范,完成了汽车的协议规范,就实现了汽车的接口,然后使用接口 接口的定义:本身 ...
- 将JAVA API接口 改写成 Python
AsinSeedApi 不写注释的程序员-加密 将JAVA API接口 改写成 Python JAVA import com.alibaba.fastjson.JSON; import com.ali ...
- QQ登录接口(第三方登录接口)
CI框架 QQ接口(第三方登录接口PHP版) 本帖内容较多,大部分都是源码,要修改的地方只有一个,其他只要复制过去,就可以完美运行.本帖主要针对CI框架,不用下载SDK,按我下面的步骤,建文件,复制代 ...
- hibernate核心接口,和扩展接口。回顾笔记,以前没记,现在补上,纯手工敲的。
hibernate核心接口: 所有的hibernate应用都会访问hibernate的5个核心接口 1,Configuration接口 Configuration用于配置并且根启动Hibernate. ...
随机推荐
- 显示python已安装模块及路径,添加修改模块搜索路径
在python交互模式下输入: help('modules') #可以显示出已安装的模块 在python交互模式下输入: import sys sys.path #可以显示出模块搜索路径 增加搜索路径 ...
- Linux 安装记录
######ubuntu-16.04.1-desktop-amd64 ||| Unity desktop Environment, NOT !!! ######deepin-15.3-amd64.is ...
- input中空格后的数据不显示
bug,input中空格后的数据不显示 昨天在修bug,有一个bug是用户修改的个人信息的地址栏,输入有空格的话,空格后面的内容存不上,而且没有报错,奇怪了,只好跟踪下. 页面上的输入框就是个 ...
- Extjs 3.4 同值合并
摘自:http://www.cnblogs.com/kunpengit/archive/2012/11/13/2768239.html/** * grid gridPanel 需要合并的表格 * ro ...
- Hdu 1081 To The Max
To The Max Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 我的第一个开源项目-logger4Net
学会学习,学会分享,学会创造. 这我的第一个开源项目.以前总觉得开源离自己很远,但通过不断学习发现,其实自己已经走在这条路上.思想就在那,只要懂得学习,懂得分享,就会懂享受创造的快乐感与殷实感. 没做 ...
- python for mysql
# -*- coding: utf-8 -*- '''python coded by written in 2016/8/31 Used for get win os log for each win ...
- 使用百度地图api接口获取公交地图路线和车站
需要在页面文件中引用百度的js @*<script type="text/javascript" src="http://api.map.baidu.com/api ...
- 浅谈UI设计中妙用无穷的深色系背景
英文:medium 译者:优设网 - 陈子木 链接:http://www.uisdc.com/ui-benefits-of-dark-background# --------------------- ...
- SQLite的优化总结
网上关于SQL优化的教程很多,但是比较杂乱.近日有空整理了一下,写出来跟大家分享一下. 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2 ...