Node.js中asynchronousrecursion的问题

我有一个关于Node.js中的recursionasynchronous请求的行为的问题。

下面的函数旨在从MongoDB返回search结果。 如果初始search结果为空,则将文本分割为单个单词,然后尝试对每个单词recursion执行fetchResult(…),将res对象作为parameter passing。

function fetchResult(text, res){ var MongoClient = require('mongodb').MongoClient; MongoClient.connect(mongoURL + "/search", function (err, db) { if(err) throw err; db.collection('results', function(err, collection) { // search for match that "begins with" text collection.findOne({'text':new RegExp('^' + text, 'i')}, function(err, items){ var result = (items == null || items.result == null) ? "" : items; if (result){ res.send(result); } else { // no result, so fire off individual word queries - if any spaces found if (text.indexOf(' ') > -1){ // split string into array var textArray = text.split(" "); // recursively process individual words for (index = 0; index < textArray.length; index++) { // ***** RACE CONDITION HERE? ***** fetchResult(textArray[index], res); } } else { // just return empty result res.send(result); } } }); }); }); } 

我怀疑这可能会导致一些竞争条件,作为参考资源asynchronous迷,这是得到证实,当我运行代码,并观察到以下错误:

 Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11) 

所以我的问题是:我怎样才能实现所需的顺序执行单个string查询的recursion行为,只有当我们find第一个结果(或在search没有返回任何结果的过程结束时)返回?

你的代码需要重构。

首先,从fetchResult函数中删除MongoClient.connect调用。 您可以连接一次并存储db对象以备后用。

其次,用您的方法,您将返回查询中每个单词的响应。 我不认为recursion电话是去这里的路。

如果你的第一个查询失败了,你将有多个asynchronous查询,而且你需要聚合结果…这是棘手的地方。 我对Mongo不太熟悉,但是我相信你可以通过find $in来检索一组结果来避免这种find $in 。 看到这个问题 ,也许它有帮助。