我一直在使用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
});
});
}
});
每次我在回调内部回调内部回写这样的东西时,我觉得我做错了。我知道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
});
});
}
});
答案 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)