【发布时间】:2013-12-19 06:38:15
【问题描述】:
我已经使用 node.js 大约 6 个月了,时断时续。但是,我想我仍然没有完全理解围绕异步调用设计程序。
以我最近的程序为例,它需要读取一个配置,使用该配置连接到数据库,然后异步连接到数据库中的每个地址。
我正在使用模块 fnoc 和 node-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
});
});
}
});
每次我写这样的东西,回调里面的回调里面的回调,我觉得我做错了什么。我知道 Promise 和异步节点库,但似乎如果这些是解决方案,它们应该是默认功能。是我做错了什么,还是只是没有为我点击?
编辑:一些建议包括使用回调函数,但这似乎更糟(除非我做错了,这是完全可能的)。你最终会在另一个函数中调用一个函数,这看起来特别像意大利面条。
上面的例子,带有函数:
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
});
});
}
});
【问题讨论】:
-
连续传递风格(适用于此,对吗?)确实需要一些时间来适应。
-
如果您正确地将其拆分为函数而不是试图将所有内容强制转换为一大段代码,那么“回调地狱”就变得易于管理。意大利面条代码总是一个糟糕的模式,无论是否回调。
-
对我来说看起来不错。您可以将回调的输出和输入分开,这使得它更易于管理(并且更重要)可组合。例如,函数式反应式编程就是这样的解决方案:bacon。然后,您实际上是在构建数据流经的电路。但老实说,你也需要用大脑思考它,因为它是一个完整的范式,而不仅仅是一个库。
标签: javascript node.js asynchronous