Javascript 递归承诺NodeJS不';不要终止
我编写了以下函数来重建一个JSON对象,该对象递归地包含。但是在执行时,它在执行时不返回任何内容,并且Javascript 递归承诺NodeJS不';不要终止,javascript,node.js,recursion,promise,async-await,Javascript,Node.js,Recursion,Promise,Async Await,我编写了以下函数来重建一个JSON对象,该对象递归地包含。但是在执行时,它在执行时不返回任何内容,并且控制台.log会一次又一次地记录相同的组件,而不会终止。有人能帮我确定这个问题吗 this.findOne = (id) => { return new Promise(resolve => { componentCollection.find(id).then(components => { if (components[0]) { l
控制台.log
会一次又一次地记录相同的组件,而不会终止。有人能帮我确定这个问题吗
this.findOne = (id) => {
return new Promise(resolve => {
componentCollection.find(id).then(components => {
if (components[0]) {
let subComponents = components[0].components;
for (let i = 0; i < subComponents.length; i++) {
console.log(subComponents[i])
subComponents[i] = resolve(this.findOne(subComponents[i].id))
}
components[0].components = subComponents;
}
resolve(components[0])
})
})
}
控制台无限日志来自Console.log(子组件[i])
:
编辑:
findOne的周边代码:
this.findone = () =>{}
module.exports = {
findOne: this.findOne
};
我在控制器中将其称为:
const ComponentService = require('./cs');
const component = await ComponentService.findOne(id)//id={1,2,...}
您好,我尝试了这种方法,当您尝试迭代它时,只需首先在数组中创建对象。 代码:-- 异步函数打印(obj){ //在数组中传递obj,然后迭代 let components=[obj] if(组件[0]){ 设子组件=组件[0]。组件; for(设i=0;i
不知道我是否正确,不过我尝试了这种方法,当你尝试迭代它时,只是先在数组中创建对象。 代码:-- 异步函数打印(obj){ //在数组中传递obj,然后迭代 let components=[obj] if(组件[0]){ 设子组件=组件[0]。组件; for(设i=0;i
不知道我是否正确,不过这里有一个使用承诺的版本。大概将其转换为
async await
很容易。它使用纯函数,而不是对象的方法。这不应该太难改变;我还没有尝试过,但您可能需要存储一个对此
的本地引用才能使其正常工作
const findOne=(id)=>新承诺(
(解决、拒绝)=>
componentCollection.find(id)。然后(
({components=[],…rest})=>
Promise.all(components.map(({id})=>findOne(id))。然后(
children=>resolve({…rest,components:children}),
拒绝
),
拒绝
)
)
findOne(5).then(console.log,console.warn)
findOne(1)。然后(console.log、console.warn)
。作为控制台包装{最小高度:100%!重要;顶部:0}
//虚拟代码只是为了演示
常量组件集合={
查找:(n)=>[1,2,3,4]。包括(n)
?承诺。决心(
n==1
?{id:1,名称:'comp1',组件:[{id:2}]}
:n==2
?{id:2,名称:'comp2',组件:[{id:3},{id:4}]}
:n==3
?{id:3,名称:'comp3'}
:{id:4,名称:'comp4'}
)
:Promise.reject(`notfound:${n}`)
}
这是一个使用承诺的版本。大概将其转换为async await
很容易。它使用纯函数,而不是对象的方法。这不应该太难改变;我还没有尝试过,但您可能需要存储一个对此
的本地引用才能使其正常工作
const findOne=(id)=>新承诺(
(解决、拒绝)=>
componentCollection.find(id)。然后(
({components=[],…rest})=>
Promise.all(components.map(({id})=>findOne(id))。然后(
children=>resolve({…rest,components:children}),
拒绝
),
拒绝
)
)
findOne(5).then(console.log,console.warn)
findOne(1)。然后(console.log、console.warn)
。作为控制台包装{最小高度:100%!重要;顶部:0}
//虚拟代码只是为了演示
常量组件集合={
查找:(n)=>[1,2,3,4]。包括(n)
?承诺。决心(
n==1
?{id:1,名称:'comp1',组件:[{id:2}]}
:n==2
?{id:2,名称:'comp2',组件:[{id:3},{id:4}]}
:n==3
?{id:3,名称:'comp3'}
:{id:4,名称:'comp4'}
)
:Promise.reject(`notfound:${n}`)
}
承诺只能解决一次。目前,您正在为循环的内多次解析它。我知道“subComponents[i]=resolve(this.findOne(subComponents[i].id))”存在问题,但我应该如何更改它?for循环不应在生成所有子组件之前退出第二次尝试似乎更好,但结果仍然相同可以显示周围的代码吗?最初如何调用findOne
?这是什么?
?这是导出函数的模块。您只能解析一次承诺。目前,您正在为循环的内多次解析它。我知道“subComponents[i]=resolve(this.findOne(subComponents[i].id))”存在问题,但我应该如何更改它?for循环不应在生成所有子组件之前退出第二次尝试似乎更好,但结果仍然相同可以显示周围的代码吗?最初如何调用findOne
?什么是此
?此模块将我添加的函数导出为我尝试构建的对象。Id是所有组件的唯一标识符。您好,您也可以给出一个输入示例。我想你不必调用递归,它可以通过Promise.All和async帮助完成。如果你想看到它,这里有链接-->我已经添加了预期输出作为我尝试构建的对象。Id是所有组件的唯一标识符。您好,您也可以给出一个输入示例。我想你不必调用递归,它可以通过Promise来完成。All和async帮助。如果你想看到它,这里有链接-->谢谢:D我可以用这个做些小改动,谢谢D我可以用这个做些小改动
{
id:2,
name:"comp2",components:[..]
}
this.findone = () =>{}
module.exports = {
findOne: this.findOne
};
const ComponentService = require('./cs');
const component = await ComponentService.findOne(id)//id={1,2,...}
async function print(obj) {
// passing your obj in array and then iterating
let components = [obj]
if (components[0]) {
let subComponents = components[0].components;
for (let i = 0; i < subComponents.length; i++) {
console.log(subComponents[i])
subComponents[i] = await print(subComponents[i])
}
components[0].components = subComponents;
}
return components[0]
}
print(obj)