node.js中异步列表处理的模式
我有一个应用程序,其中数据库查询返回许多行(通常小于100行)。对于每一行,我需要进行http调用以获取补充数据。我希望触发所有请求,然后在最后一次回调完成后,继续呈现结果页 到目前为止,我所看到的类似问题的答案要么是通过在请求1的回调中发出请求2来链接请求(优点:简单,避免将服务器埋在多个请求中),要么是在不跟踪所有请求是否已完成的情况下触发所有请求(在回调更新UI的浏览器中运行良好) 我目前的计划是保留一个请求计数器,并让回调函数递减计数器;如果计数器为零,我可以调用render函数。我可能还需要处理响应比请求更快的情况(不太可能,但可能是边缘情况) 对于这类问题,还有其他有用的模式吗?当使用代码时,大致如下所示:node.js中异步列表处理的模式,node.js,design-patterns,asynchronous,Node.js,Design Patterns,Asynchronous,我有一个应用程序,其中数据库查询返回许多行(通常小于100行)。对于每一行,我需要进行http调用以获取补充数据。我希望触发所有请求,然后在最后一次回调完成后,继续呈现结果页 到目前为止,我所看到的类似问题的答案要么是通过在请求1的回调中发出请求2来链接请求(优点:简单,避免将服务器埋在多个请求中),要么是在不跟踪所有请求是否已完成的情况下触发所有请求(在回调更新UI的浏览器中运行良好) 我目前的计划是保留一个请求计数器,并让回调函数递减计数器;如果计数器为零,我可以调用render函数。我可能
var async = require('async');
results = [];
var queue = async.queue(function(row, callback) {
http.fetchResultForRow(row, function(data){
result.push(data);
callback();
});
}, 1);
queue.drain = function() {
console.log("All results loaded");
renderEverything(results);
}
database.fetch(function(rows) {
for (var i=0; i < rows.length; i++) {
queue.push(rows[i]);
}
});
var async=require('async');
结果=[];
var queue=async.queue(函数(行,回调){
http.fetchResultForRow(行,函数(数据){
结果:推送(数据);
回调();
});
}, 1);
queue.drain=函数(){
console.log(“加载的所有结果”);
渲染(结果);
}
database.fetch(函数(行){
对于(变量i=0;i
如果订单不重要,您也可以使用:
看看异步的文档,有很多有用的模式。你可以使用
when
库很好地实现这一点。不过,如果你想对获取额外信息的调用进行评级,你需要比Hippo的异步方法做更多的工作
下面是一个例子:
when = require('when')
// This is the function that gets the extra info.
// I've added a setTimeout to show how it is async.
function get_extra_info_for_row(x, callback) {
setTimeout( function(){ return callback(null, x+10); }, 1 );
};
rows = [1,2,3,4,5];
row_promises = rows.map(
function(x) {
var defered = when.defer()
get_extra_info_for_row(x, function(err,extra_info) {
if(err) return defered.reject(err);
defered.resolve([x,extra_info]);
});
return defered.promise;
})
when.all( row_promises )
.then(
function(augmented_rows) { console.log( augmented_rows ); },
function(err) { console.log("Error", err ); }
);
这个输出
[ [ 1, 11 ], [ 2, 12 ], [ 3, 13 ], [ 4, 14 ], [ 5, 15 ] ]
queue
中的函数正是您想要的。也可以用于此。我决定使用async,因为它内置了速率限制,但这看起来也很有希望。