Javascript Mongoose中的承诺递归返回问题

Javascript Mongoose中的承诺递归返回问题,javascript,json,node.js,mongoose,promise,Javascript,Json,Node.js,Mongoose,Promise,我正在与Mongoose的承诺作斗争,因为我习惯于同步编程 上下文 我有很多类别。每个类别没有父类别或只有一个父类别。 知识与类别相关联。 我想创建一个包含所有类别及其子类别和知识的树 实际上,它看起来像一个带有目录和文件的模型。 预期的输出类似于JSON: [ {"name": "cat0", "children": [{"name": know0}] }, {"name": "cat1", ... ] 代码 findKnowledgeByCate

我正在与Mongoose的承诺作斗争,因为我习惯于同步编程

上下文

我有很多类别。每个类别没有父类别或只有一个父类别。 知识与类别相关联。 我想创建一个包含所有类别及其子类别和知识的树

实际上,它看起来像一个带有目录文件的模型。 预期的输出类似于JSON:

[
    {"name": "cat0",
     "children": [{"name": know0}]
    },
    {"name": "cat1",
    ...
]
代码

findKnowledgeByCategory()
        .then((catAndKnow) => res.status(200).json(catAndKnow))
        .catch(err => Validation.handleError(res, 500, err));
我使用递归的方法。我使用null调用函数(它获取所有根类别),然后递归调用将应用于子类别

static findKnowledgeByCategory(query = null){


    return new Promise((resolve, reject) => {
        CategoryModel.find({parent: query})
            .then((categories) => {
                console.log(query + ' : CategoryModel.find success');
                return new Promise((resolve, reject) => {
                    console.log(query + ' : new Promise');
                    categories.forEach(cat => { // cat == { _id: ..., parent: ..., name: 'smthng' }
                        KnowledgeModel.find({category: cat._id})
                            .then((knowledges) => {
                                console.log(query + ' : KnowledgeModel.find success');
                                cat.knowledges = knowledges;
                                Model.findKnowledgeByCategory(cat._id)
                                    .then((categories) =>{
                                        cat.children = categories;
                                    });
                            })
                    })
                }).then(() => {
                    console.log(query + ' : Début resolve');
                    return resolve(categories);
                })
            })
            .catch((err) =>{
                console.log(err);
                return reject();
            } )
    });

}
我必须用这段代码返回一个承诺,因为在更全局的范围内,它的解析用于返回JSON中的树

全球范围

findKnowledgeByCategory()
        .then((catAndKnow) => res.status(200).json(catAndKnow))
        .catch(err => Validation.handleError(res, 500, err));
没有显示错误,但是当我调用函数时,服务器没有响应

请注意,它永远不会显示“Début resolve”。。。 我正在使用节点6.11.2,所以不能使用“等待”。
任何想法都将不胜感激。如果我的问题与此无关,我深表歉意。我想我没有很好地履行我的承诺,但我没有任何线索。

看看这部分代码:

return new Promise((resolve, reject) => {
    console.log(query + ' : new Promise');
    categories.forEach(cat => { 
        KnowledgeModel.find({category: cat._id})
            .then((knowledges) => {
                console.log(query + ' : KnowledgeModel.find success');
                cat.knowledges = knowledges;
                Model.findKnowledgeByCategory(cat._id)
                .then((categories) =>{
                    cat.children = categories;
                });
        })
    })
})
您从未在此承诺内调用
resolve
reject
,因此它从未被解决。尝试将代码拆分为较小的函数,然后将它们排列在一起—这样更容易捕捉到这种情况。

您不应该使用。由于您的方法调用(如
find
)已经产生承诺,您应该返回附加到这些承诺的承诺链

其次,保持你的嵌套水平:承诺就是因为这个原因而产生的,所以不要嵌套
然后
调用,而是尽快将承诺返回到外链,然后在那里链接一个
然后
调用

最后,当您在
forEach
中创建承诺时,您需要以某种方式将这些承诺组合成一个承诺<代码>承诺。所有的都只是补救措施。因此,不要使用
forEach
,而是在回调中使用
map
返回承诺,并将结果传递给
Promise.all

以下是代码的外观(未经测试):


这是第六级回叫地狱。您确实需要将此代码分解为更小的片段、函数或异步/等待块。或者使用模块。因为现在的调试就是它被称为地狱的原因。谢谢你的回复。为了解释这一点,我尝试在forEach()阵营之后放置一个resolve(),但这不是我想要的。因为它将实现承诺,尽管循环尚未完成。如何处理(换句话说,承诺中的同步过程)?我也尝试了没有“返回”,但没有更好的结果。通过使用
category.forEach
,您正在迭代每个类别,并对每个类别执行一些查询。这意味着您应该等待所有查询结束。看看这个方法。但首先,请尝试将这个大函数重新组织为较小的函数,并将它们组合在一起-这将使代码更具可读性。谢谢您的帮助。看起来它没有进入then(children)中,但我想我自己可以找到。如果执行没有到达
然后
回调,请检查
知识模型。find({category:cat.\u id})
承诺可能会拒绝而不是履行。你可以在
之后链接一个
。catch
,然后((儿童)
来检查。事实上,我刚才注意到了。谢谢。谢谢你的反馈。