如何避免Node.js中异步函数的长时间嵌套
我想创建一个页面来显示数据库中的一些数据,所以我创建了一些从我的数据库中获取数据的函数。 我只是Node.js中的一个新手,据我所知,如果我想在单个页面中使用它们(HTTP响应),我必须将它们全部嵌套在一起:
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();
});
});
});
如果有这样的功能,那么嵌套就成了一个问题 。
有没有办法避免这种情况? 我想这与你如何组合多个异步函数有关,这似乎是一些基本的东西。
有趣的观察。 请注意,在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在下面的注释中提到,如果您正在访问内部函数中的闭包变量,上述内容将不是一个简单的翻译。 在这种情况下,使用内联匿名函数更为可取。
凯,只需使用这些模块之一。
它会变成这样:
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()
}
);
大多数情况下,我会同意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();
});
});
这种方法的一个好处是,您可以快速更改代码以通过将“系列”功能更改为“并行”来并行获取数据。 更重要的是,async.js也可以在浏览器内部工作,所以你可以使用和你在node.js中一样的方法,如果你遇到任何棘手的异步代码。
希望这很有用!
链接地址: http://www.djcxy.com/p/79299.html上一篇: How to avoid long nesting of asynchronous functions in Node.js
下一篇: What's the difference between Invoke() and BeginInvoke()