【问题标题】:any way to make nested callback code in javascript more readable?有什么方法可以使javascript中的嵌套回调代码更具可读性?
【发布时间】:2012-06-29 02:43:28
【问题描述】:

考虑一下这段简单的代码

pg.connect( {
    user: 'hhope',
    password: '...',
    port: 5432,
    host: '/var/run/postgresql',
    database: 'phiddler' },
  function( err, client ) {
    client.query(
      "select count(1) as ct from pg_prepared_statements",
      function( err, results ) {
        console.log( 'prepared statement count: '+results.rows[0].ct );
        client.query( {
                    name: 'test2' ,
                    text: "insert into t1( c2 ) values( 'q1')" },
          function( err, result ) {
            console.log( 'inserted t1' );
            client.query(
              "select count(1) as ct from pg_prepared_statements",
               function( err, results ) {
                  console.log( 'prepared statement count: '+results.rows[0].ct );
               } );
           }
        );
      }
    );
  }
);

如果是按程序编写的话

pg = new PG(...);
client = new pg.client();
console.log( client.col( "select ..." ) );
client.prepare( 'test2', "insert into t1( c2 ) values( 'q1')" );
console.log( client.col( "select ..." ) );

在我看来,后者更具可读性和可维护性。

是否有某种折衷方法可以使标准缩进回调样式更具可读性?

【问题讨论】:

标签: javascript node.js syntax callback


【解决方案1】:

您想使用async 库的waterfall 机制:

var async = require('async');

async.waterfall([
    pg.connect.bind(this, {
        user: 'user', password: 'pass', port: 5432, host: '/somewhere/', database: 'db'
    }),
    function(client, callback) {
        client.query('select * from foo', callback)
    }
], function(err, results) {
    console.log(results);
});

在 ES5 中添加到 Functions 的 bind 方法非常与异步库结合使用非常有用,因为列表中的最后一个参数通常是回调,而早期的值是通常在进入链条之前就知道了。

【讨论】:

    【解决方案2】:

    程序变体并不真正等效 - 我假设它是同步的,而原始变体可能不是。

    如果你不需要关闭变量,你可以使用命名函数。比如:

    function f2(){}
    function f1() {
        client.query("select count(1) as ct from pg_prepared_statements", f2);
    }
    pg.connect( {
        user: 'hhope',
        password: '...',
        port: 5432,
        host: '/var/run/postgresql',
        database: 'phiddler' },
        f1
    );
    

    【讨论】:

    • connect 方法将client 对象传递到它的回调中,这样写就行不通了。
    • 同意它们不相等,后者是同步的(如您所说)。没有进行变量赋值,因为不希望人们解决是否可以在一对两个客户端调用中完成,而不是语法本身。同意,可以命名 funcs,但恕我直言,两个弊端更糟。
    【解决方案3】:

    “可读”是一个见仁见智的问题,但您可以这样做:

    var iter = function(cb) {
       var v = Array.prototype.slice.call(arguments);
       var f = function() {
            var g = v.shift();
            g && g(f);
       };
    
       f();
    };
    
    iter(function(cb) {
            console.log('in f1');
            cb();
         },
         function(cb) {
            console.log('in f2');
            cb();
         });
    

    【讨论】:

      猜你喜欢
      • 2017-05-23
      • 2012-07-02
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多