Javascript 递归回调以创建家族树
我正在尝试创建一个带有嵌套在回调函数中的回调函数的族谱,我希望得到至少5代。函数接收个人id,然后查找数据库中具有相同id的属性“父”的所有人Javascript 递归回调以创建家族树,javascript,recursion,keystonejs,Javascript,Recursion,Keystonejs,我正在尝试创建一个带有嵌套在回调函数中的回调函数的族谱,我希望得到至少5代。函数接收个人id,然后查找数据库中具有相同id的属性“父”的所有人 这是获取该人的子女的函数 var getChildren=function (person, callback) { keystone.list('Person').model.find().where('father', person.id).exec(function(err, children) { cal
这是获取该人的子女的函数
var getChildren=function (person, callback) {
keystone.list('Person').model.find().where('father', person.id).exec(function(err, children) {
callback(children);
})
}
这就是我如何使用回调函数
function getFamilyTree(person){
getChildren(person, function(children){
person.children=children;
for (var i=0;i<person.children.length;i++) {
!function outer(i){
if (isNotEmpty(person.children[i])){
getChildren(person.children[i],function(children){
person.children[i].children=children;
for (var j=0;j<person.children[i].children.length;j++){
!function outer(j){
if (isNotEmpty(person.children[i].children[j])){
getChildren(person.children[i].children[j],function(children){
person.children[i].children[j].children=children;
for (var k=0;k<person.children[i].children[j].children.length;k++){
!function outer(k){
if (isNotEmpty(person.children[i].children[j].children[k])){
getChildren(person.children[i].children[j].children[k],function(children){
person.children[i].children[j].children[k].children=children;
})
}
}(k);
}
})
}
}(j);
}
});
}
}(i);
}
})
}
函数getFamilyTree(个人){
getChildren(个人、功能(儿童){
人.儿童=儿童;
对于(var i=0;i您肯定需要使用递归。我不知道您的数据看起来如何,或者getChildren
如何工作,但这应该为您指明了正确的方向:
function getFamilyTree ( person ) {
getChildren( person, function( children ) {
person.children = children;
for ( var i = 0; i < person.children.length ) {
getFamilyTree( person.children[ i ] );
}
})
}
函数getFamilyTree(个人){
getChildren(个人、功能(儿童){
person.children=儿童;
对于(变量i=0;i
您肯定需要使用递归。我不知道您的数据是什么样子的,或者getChildren
是如何工作的,但这应该为您指明了正确的方向:
function getFamilyTree ( person ) {
getChildren( person, function( children ) {
person.children = children;
for ( var i = 0; i < person.children.length ) {
getFamilyTree( person.children[ i ] );
}
})
}
函数getFamilyTree(个人){
getChildren(个人、功能(儿童){
person.children=儿童;
对于(变量i=0;i
如果使用而不是回调,则可以使用递归来解析任意深度的树:
函数getChildren(person){
返回新承诺((解决、拒绝)=>{
keystone.list('Person').model.find().where('father',Person.id).exec((err,children)=>{
如果(错误)拒绝(错误);
(儿童);
});
});
}
异步函数getFamilyTree(person,maxDepth,depth=0){
如果(深度>=最大深度)返回人员;
const children=(wait getChildren(person)).filter(isNotEmpty);
person.children=等待承诺(
map(child=>getFamilyTree(child,maxDepth,depth+1))
);
返回人;
}
getFamilyTree({id:'rootPersonId'},5)
.then(tree=>console.log(tree))
.catch(错误=>console.log(错误));
如果使用而不是回调,则可以使用递归来解析任意深度的树:
函数getChildren(person){
返回新承诺((解决、拒绝)=>{
keystone.list('Person').model.find().where('father',Person.id).exec((err,children)=>{
如果(错误)拒绝(错误);
(儿童);
});
});
}
异步函数getFamilyTree(person,maxDepth,depth=0){
如果(深度>=最大深度)返回人员;
const children=(wait getChildren(person)).filter(isNotEmpty);
person.children=等待承诺(
map(child=>getFamilyTree(child,maxDepth,depth+1))
);
返回人;
}
getFamilyTree({id:'rootPersonId'},5)
.then(tree=>console.log(tree))
.catch(错误=>console.log(错误));
简化代码的第一件事是拉出在
getFamilyTree
函数中多次使用的外部
函数,这样就不会到处重复。为了简单起见,需要更新以将子节点作为参数而不是索引
由于您的回调每次都是相同的,因此您可以将其拉出到它自己的函数中。由于您在整个回调过程中不断引用person
变量,因此需要对父项进行轻微更新
您的外部
功能可以是:
function outer(child) {
if (isNotEmpty(child)) {
getChildren(child, getChildrenCallback);
}
}
然后,getChildrenCallback
将是:
function getChildrenCallback(children, parent) {
parent.children = children;
for ( var i = 0; i < children.length; i++) {
outer(child[i]);
}
函数getChildrenCallback(子对象、父对象){
parent.children=children;
对于(变量i=0;i}简化代码的第一件事是拉出在
getFamilyTree
函数中多次使用的outer
函数,这样就不会到处重复。为了简单起见,需要更新以将子节点作为参数而不是索引
由于您的回调每次都是相同的,因此您可以将其拉出到它自己的函数中。由于您在整个回调过程中不断引用person
变量,因此需要对父项进行轻微更新
您的外部
功能可以是:
function outer(child) {
if (isNotEmpty(child)) {
getChildren(child, getChildrenCallback);
}
}
然后,getChildrenCallback
将是:
function getChildrenCallback(children, parent) {
parent.children = children;
for ( var i = 0; i < children.length; i++) {
outer(child[i]);
}
函数getChildrenCallback(子对象、父对象){
parent.children=children;
对于(变量i=0;i}非常感谢您的评论,因为前端是如何工作的,我需要检索此人的完整JSON家族树。此外,我尝试了您的代码,但它只检索了一代人,我不知道为什么我会在那里抛出一些
控制台。log
调用。我不认为这种逻辑是错误的,但很难知道w没有看到getChildren
调用的结果或您正在查询的数据。因此,通过使用getChildren,它将以对象数组的形式检索个人的子对象,每个对象将包含关于每个子对象的信息。当个人没有任何子对象时,它将返回一个空白数组。非常感谢您的帮助注释,由于前端的工作方式,我需要检索此人的完整JSON族谱。此外,我尝试了您的代码,但它只检索了一代人,我不知道为什么我会在那里抛出一些console.log
调用。我不认为这一逻辑是错误的,但如果没有看到res,很难知道getChildren
调用的结果或您正在查询的数据。因此,通过使用getChildren,它将以对象数组的形式检索个人的子对象,每个对象将包含有关ea的信息