Javascript 我想我不知道';";获得;异步编程
我已经断断续续地使用node.js大约6个月了。但是,我想我仍然不完全理解围绕异步调用设计程序 例如,我的最新程序需要读取配置,使用该配置连接到数据库,然后异步连接到数据库中的每个地址 我正在使用模块和,但这只是伪代码Javascript 我想我不知道';";获得;异步编程,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我已经断断续续地使用node.js大约6个月了。但是,我想我仍然不完全理解围绕异步调用设计程序 例如,我的最新程序需要读取配置,使用该配置连接到数据库,然后异步连接到数据库中的每个地址 我正在使用模块和,但这只是伪代码 // first, get the config fnoc(function(err, confs){ // code stuff in here //now check that there's a database config if (confs.has
// 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
});
});
}
});
每次我用callback-in-in-in-in-of-callback写这样的东西时,我都觉得自己做错了什么。我知道promises和async节点库,但如果这些是解决方案,它们应该是默认功能。是我做错了什么,还是它没有为我点击
编辑:一些建议包括对回调使用函数,但这似乎更糟(除非我做错了,这是完全可能的)。你最终在一个函数中调用另一个函数,它看起来特别像意大利面条
上面的示例包含以下功能:
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
});
});
}
});
简而言之:代替
foo(function () {
// ... stuff #1 ...
bar(function () {
// ... stuff #2 ...
baz();
});
});
做
当然,它可以(也可能应该)更细粒度,但这取决于实际代码。这只是一种避免嵌套函数的模式。您还可以更多地封装这些方法
这是“普通”方法。还有一些库允许您以很好的方式管理它。异步函数和回调的目的是避免对象之间发生任何冲突(可能比您想象的要多!) 我想向您介绍这位异步爱好者:
是的,回调确实需要一些时间来适应,但它是值得的 如果你真的对没完没了的回电感到厌倦,那就试试看。您可以这样编写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);
})()
这几乎是一种不同的编写方式,因此可能很难掌握,但结果非常好。继续传递样式(适用于此,对吗?)确实需要一些时间来适应。如果您将其正确地拆分为函数,而不是试图将所有内容强制转换为一大块代码,“回调地狱”将变得可管理。意大利面代码总是一种糟糕的模式,不管是回调还是不回调。我觉得它很好。您可以将回调的输出和输入分开,这使得它更易于管理(也更重要)可组合。例如,函数式反应式编程就是这样一种解决方案:。然后,您实际上是在构建电路,数据在其中流动。但是要成为hones,你也需要把你的大脑围绕在它周围,因为它是一个完整的范例,而不仅仅是一个库。我考虑过这一点,但我不会在另一个函数中调用一个函数(比如在config read函数中调用数据库查询函数?)?不知怎么的,它看起来更糟糕。如果做得正确(例如,在封装步骤的“逐步模式”中),它就不是垃圾邮件。是的,函数调用仍然是嵌套的,但这绝对没有错。你可以使用的任何库都会做同样的事情,只是可能“在幕后”。我只同意,有了这样的图书馆,麻省理工学院可能会a)更舒适,b)外观和感觉更干净,即使技术上是一样的。无论如何,适当的分离绝对不是一种反模式。耶,几个月前我和Q做了一些承诺。这很酷,但我觉得在我开始使用快捷方式之前,我应该先了解事情应该如何运作。@coding_hero承诺不是回调的快捷方式,而且工作方式完全不同。事实上,为了从承诺中获得最大的好处,您需要忘记所有关于回调的事情,因为在使用承诺时,任何回调的想法都会导致非常糟糕的代码(这可能是大多数人看不到承诺lol优势的主要原因)。回调的质量很差,任何学习回调的方法都是浪费时间,甚至是有害的——几乎所有其他语言都使用异步承诺,而不是回调。这个博客链接很特别,特别是因为我在做他所说的每一种语言。我会用这个。
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);
})()