我将您的代码示例简化为以下几行,以使您更容易理解该概念。
var results = [];var config = JSON.parse(queries);for (var key in config) { var query = config[key].query; search(query, function(result) { results.push(result); });}res.writeHead( ... );res.end(results);先前代码的问题在于该
search函数是异步的,因此在循环结束时,没有调用任何回调函数。因此,的列表
results为空。
要解决此问题,您必须将代码放在循环后的回调函数中。
search(query, function(result) { results.push(result); // Put res.writeHead( ... ) and res.end(results) here });但是,由于多次调用了回调函数(每次迭代一次),因此您需要以某种方式知道所有回调都已被调用。为此,您需要计算回调的数量,并检查该数量是否等于异步函数调用的数量。
这是一个完整的示例:
var results = [];var config = JSON.parse(queries);var onComplete = function() { res.writeHead( ... ); res.end(results);};var keys = Object.keys(config);var tasksToGo = keys.length;if (tasksToGo === 0) { onComplete();} else { // There is at least one element, so the callback will be called. keys.forEach(function(key) { var query = config[key].query; search(query, function(result) { results.push(result); if (--tasksToGo === 0) { // No tasks left, good to go onComplete(); } }); });}注意:上一个示例中的异步代码是并行执行的。如果需要按特定顺序调用函数,则可以使用递归获得所需的效果:
var results = [];var config = JSON.parse(queries);var keys = Object.keys(config);(function next(index) { if (index === keys.length) { // No items left res.writeHead( ... ); res.end(results); return; } var key = keys[index]; var query = config[key].query; search(query, function(result) { results.push(result); next(index + 1); });})(0);我所展示的是概念,您可以在实现中使用许多(第三方)NodeJS模块之一,例如async。



