我想创建一个页面来显示数据库中的一些数据,所以我创建了一些从数据库中获取数据的函数。我只是Node.js的新手,所以据我所知,如果我想在一个页面(超文本传输协议响应)中使用它们,我必须将它们全部嵌套:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
var html = "<h1>Demo page</h1>";
getSomeDate(client, function(someData) {
html += "<p>"+ someData +"</p>";
getSomeOtherDate(client, function(someOtherData) {
html += "<p>"+ someOtherData +"</p>";
getMoreData(client, function(moreData) {
html += "<p>"+ moreData +"</p>";
res.write(html);
res.end();
});
});
});
如果有很多这样的函数,那么嵌套就成了一个问题的。
有没有办法避免这种情况?我猜这与如何组合多个异步函数有关,这似乎是一些基本的东西。
发布于 2010-11-21 03:56:26
有趣的观察。请注意,在JavaScript中,您通常可以用命名函数变量替换内联匿名回调函数。
以下内容:
http.createServer(function (req, res) {
// inline callback function ...
getSomeData(client, function (someData) {
// another inline callback function ...
getMoreData(client, function(moreData) {
// one more inline callback function ...
});
});
// etc ...
});
可以重写为如下所示:
var moreDataParser = function (moreData) {
// date parsing logic
};
var someDataParser = function (someData) {
// some data parsing logic
getMoreData(client, moreDataParser);
};
var createServerCallback = function (req, res) {
// create server logic
getSomeData(client, someDataParser);
// etc ...
};
http.createServer(createServerCallback);
但是,除非您打算在其他地方重用回调逻辑,否则读取内联匿名函数通常要容易得多,如您的示例所示。它还将使您不必为所有回调函数查找名称。
此外,请注意,正如@pst在下面的注释中指出的那样,如果您要访问内部函数中的闭包变量,上面的转换将不是一个直接的转换。在这种情况下,使用内联匿名函数甚至更可取。
发布于 2010-11-27 08:07:58
Kay,只需使用这些模块中的一个。
它将会变成这样:
dbGet('userIdOf:bobvance', function(userId) {
dbSet('user:' + userId + ':email', 'bobvance@potato.egg', function() {
dbSet('user:' + userId + ':firstName', 'Bob', function() {
dbSet('user:' + userId + ':lastName', 'Vance', function() {
okWeAreDone();
});
});
});
});
如下所示:
flow.exec(
function() {
dbGet('userIdOf:bobvance', this);
},function(userId) {
dbSet('user:' + userId + ':email', 'bobvance@potato.egg', this.MULTI());
dbSet('user:' + userId + ':firstName', 'Bob', this.MULTI());
dbSet('user:' + userId + ':lastName', 'Vance', this.MULTI());
},function() {
okWeAreDone()
}
);
发布于 2010-11-22 00:11:41
在很大程度上,我同意Daniel Vassallo的观点。如果您可以将一个复杂且嵌套很深的函数分解为单独的命名函数,那么这通常是一个好主意。如果有必要在单个函数中执行此操作,您可以使用众多可用的node.js异步库中的一个。人们已经想出了很多不同的方法来解决这个问题,所以看看node.js模块页面,看看你的想法。
为此,我自己编写了一个模块,名为async.js。使用此方法,可以将上面的示例更新为:
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
async.series({
someData: async.apply(getSomeDate, client),
someOtherData: async.apply(getSomeOtherDate, client),
moreData: async.apply(getMoreData, client)
},
function (err, results) {
var html = "<h1>Demo page</h1>";
html += "<p>" + results.someData + "</p>";
html += "<p>" + results.someOtherData + "</p>";
html += "<p>" + results.moreData + "</p>";
res.write(html);
res.end();
});
});
这种方法的一个好处是,您可以通过将“series”函数更改为“parallel”来快速更改代码以并行获取数据。更重要的是,async.js还可以在浏览器内部工作,所以如果您遇到任何棘手的异步代码,您可以使用与在node.js中相同的方法。
希望这对你有用!
https://stackoverflow.com/questions/4234619
复制相似问题