zoukankan      html  css  js  c++  java
  • 如何把 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

  • 相关阅读:
    微信小程序 单选按钮 最佳
    微信小程序 单选按钮的实现
    微信小程序 单选框实现
    Java Code To Create Pyramid and Pattern
    Java language
    npm Err! Unexpected end of JSON input while parsing near
    Node.js Express FrameWork Tutorial
    Higher-Order Function Examples
    Create First HTTP Web Server in Node.js: Complete Tutorial
    Node.js NPM Tutorial: Create, Publish, Extend & Manage
  • 原文地址:https://www.cnblogs.com/hsprout/p/5588859.html
Copyright © 2011-2022 走看看