我想我不会“得到”异步编程

时间:2013-12-18 21:47:50

标签: javascript node.js asynchronous

我一直在使用node.js大约6个月了,不停用。但是,我想我仍然不完全理解围绕异步调用设计程序。

以我最近的程序为例,它需要读取一个配置,使用该配置连接到数据库,然后异步连接到数据库中的每个地址。​​

我正在使用模块fnocnode-mysql,但这只是伪代码。

// first, get the config
fnoc(function(err, confs){
   // code stuff in here

   //now check that there's a database config
   if (confs.hasOwnProperty("database"))
   {
      // set up db connection
      var mysql_conn = mysql.createConnection({
          host:   confs.database.host,
          user:   confs.database.user,
          password:       confs.database.password,
          database:       confs.database.database
      });
      // do some querying here.
      mysql_conn.query(query, function(err, records, fields){
          records.forEach(function(host){
              // four levels in, and just now starting the device connections
          });
      });


   }
});

每次我在回调内部回调内部回写这样的东西时,我觉得我做错了。我知道promises和异步节点库,但似乎这些是解决方案,它们应该是默认功能。我做错了什么,还是只是没有点击我?

编辑:一些建议包括使用函数进行回调,但这看起来更糟糕(除非我做错了,这完全有可能)。你最终在另一个内部调用了一个函数,它似乎特别是spaghetti-ish。

上面的例子,功能:

function make_connection (hosts) {
hosts.foreach(function(host){
      //here's where the fun starts
    };
}


function query_db(dbinfo){
    var mysql_conn = mysql.createConnection({
          host:  dbinfo.host,
          user:  dbinfo.user,
          password:       dbinfo.password,
          database:       dbinfo.database
    });

// do some querying here.
    mysql_conn.query(query, function(err, records, fields){
    make_connection(records);
});

}



// first, get the config
fnoc(function(err, confs){
   // code stuff in here

   //now check that there's a database config
   if (confs.hasOwnProperty("database"))
   {
      // set up db connection

      query_db(confs.database);
      var mysql_conn = mysql.createConnection({
          host:   confs.database.host,
          user:   confs.database.user,
          password:       confs.database.password,
          database:       confs.database.database
      });
      // do some querying here.
      mysql_conn.query(query, function(err, records, fields){
          records.forEach(function(host){
              // four levels in, and just now starting the device connections
          });
      });


   }
});

3 个答案:

答案 0 :(得分:1)

异步函数和回调的目的是避免在对象之间发生任何冲突(可能比你想象的更多!)。

我想指出这位asynch爱好者:http://www.sebastianseilund.com/nodejs-async-in-practice

是的,回调确实需要一些使用,但它是值得的!

答案 1 :(得分:0)

简而言之:而不是

foo(function () {
    // ... stuff #1 ...

    bar(function () {
        // ... stuff #2 ...

        baz();
    });
});

DO

foo(handleFoo);

function handleFoo() {
    // ... stuff #1 ...

    bar(handleBar);
}

function handleBar() {
    // ... stuff #2 ...

    baz();
}

当然,它可以(也许应该)更精细,但这取决于实际的代码。这只是一种避免嵌套功能的模式。您还可以更多地封装这些方法。

这是“香草”方法。还有一些库可以让你以很好的方式管理它。

答案 2 :(得分:0)

如果您对无休止的回调感到厌倦,请尝试Qco。您可以像这样编写node.js代码:

co(function *(){
  var a = get('http://google.com');
  var b = get('http://yahoo.com');
  var c = get('http://cloudup.com');
  var res = yield [a, b, c];
  console.log(res);
})()

这几乎是一种不同的写作方式,因此很难掌握,但结果非常好。