• 如何把 Callback 接口包装成 Promise 接口


    最近一段时间一直在看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

  • 相关阅读:
    关于拉格朗日乘子法和KKT条件
    深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件
    安全模式下运行Windows installer并卸载程序
    win10 进入安全模式的方法
    支持向量机通俗导论(理解SVM的三层境界)
    Windows系统防火墙用法
    浏览器起始页被篡改恶意跳转解决方法
    网络熟知端口号
    SSL/TLS协议运行机制的概述
    分布式拒绝服务攻击 DDoS
  • 原文地址:https://www.cnblogs.com/hsprout/p/5588859.html
Copyright © 2020-2023  润新知