Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何避免/防止Node.js中的无限递归调用?_Javascript_Node.js_Mongodb_Recursion - Fatal编程技术网

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时,以错误停止。