Javascript 如何避免/防止Node.js中的无限递归调用?
我在我的Javascript 如何避免/防止Node.js中的无限递归调用?,javascript,node.js,mongodb,recursion,Javascript,Node.js,Mongodb,Recursion,我在我的Node.js应用程序中有一个javascript函数,它调用自己在MongoDB的父子层次结构中查找自己的级别。文档将尝试查找其父级,如果找到,将增加级别并继续,直到找不到父级。看起来是这样的, function findLevel(doc, level, callback){ if(!doc) return callback(null, level); var query = { id: doc.parentID };
Node.js
应用程序中有一个javascript函数,它调用自己在MongoDB的父子层次结构中查找自己的级别。文档将尝试查找其父级,如果找到,将增加级别并继续,直到找不到父级。看起来是这样的,
function findLevel(doc, level, callback){
if(!doc)
return callback(null, level);
var query = {
id: doc.parentID
};
model.findOne(query, function(err, parentDoc){
if(err){
return callback(err, level)
};
return findLevel(parentDoc, level+1, callback);
})
}
这很有可能产生无限递归调用。其中一种情况是parentID与当前文档的id相同。这可以通过在find query中包含另一个条件来避免,但我仍然担心我可能会遗漏一些内容,这可能会导致整个应用程序崩溃/终止。在
Node.js
中,有没有建议避免/防止这种情况的方法?或者我们可以限制递归调用的级别并优雅地停止它,就像说递归调用应该只执行到此n
级别一样?您可以通过记录在递归过程中遇到的所有ID来实现循环检测,并在之前处理过ID后立即停止
function findLevel(doc, callback) {
var level = 0, seen = {};
(function getParent(doc) {
// proper termination
if(!doc || !doc.parentID) return callback(null, level);
// cycle detection
if (seen.hasOwnProperty(doc.parentID)) return callback(new Error("cycle detected"));
seen[doc.parentID] = true;
// recursion
model.findOne({id: doc.parentID}, function (err, parentDoc) {
if (err) return callback(err);
level++;
getParent(parentDoc);
});
})(doc);
}
当返回的父级文档id与查询id相同时,这就是您停止的点,对吗?如果您真的只关心顶级父级,为什么不在保存文档时,使用顶级父级的id保存它。或者在某个时间运行批处理作业来进行路径压缩。@Sikorski否。在一个完美的情况下,当找不到父级时,我们会停止。当然,是的,一个请求将被挂起:-)(获取其中许多请求最终将耗尽资源)。在
level
上设置一个界限,或者保存已访问图节点的历史记录,这绝对是一个好主意。另一种方法是收集您看到的所有ID,并在递归将您带到以前看到的ID时,以错误停止。