设为首页 收藏本站
查看: 1545|回复: 0

[经验分享] 如何把 Callback 接口包装成 Promise 接口

[复制链接]

尚未签到

发表于 2017-2-25 10:32:13 | 显示全部楼层 |阅读模式
  最近一段时间一直在看Node.js,在开发过程中经常要调用一些异步接口,通常在接口的最后一个参数会传入一个回调函数,可以用来处理异常,非异常情况。大致模式如下:



1 var fs = require(“fs");
2 fs.readFile(filename, "binary", function(err, file){
3     if(err){
4         //异常情况
5    }else{
6        //正常情况
7     }
8 });            
  但是,这种写法遇上比较复杂的逻辑时,就很容易出现 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这个函数,就可以把接口进行转换。
  上面的模板就可以改成下面的形式:



1 var fs = require("fs");
2 var readFilePromise = promisify(fs.readFile, fs); //包装为Promise接口
3 readFilePromise(filename, "binary").then(function(file){
4      //正常情况
5 }).catch(function(err){
6      //异常情况
7 })
  特殊情况
  有些设计不合理的接口可能会传递多个值给回调函数,如:



1 var fn = function(foo, callback){
2       if(success){
3             callback(null, file1, file2);
4       }else{
5             callback(err);
6       }
7 }
  很明显 这个接口传了 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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-346938-1-1.html 上篇帖子: iframe大小自适应 下篇帖子: 聊聊asp.net中Web Api的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表