如何在异步映射功能上执行递归

时间:2019-03-15 13:53:51

标签: javascript mongodb algorithm graph

我有一个标签名称的图表,例如咖啡,鞋子等。每个标签可以有多个父母或子女。我正在用那棵树。我选择了没有父节点的那些节点,然后从那里开始遍历。我的mongo ID

  Taxonomy.find($or: [{ 'parent': { $exists: false } }]}).then((resp) => {
    Promise.all(resp.map(resp) => getChildCategories(resp.children)).then(function(results) {
        resp.children = results
        res.json({resp});
    }).catch(err => {
        console.log(err)
    });
});

但是当出现循环条件时,例如标签中有一个孩子,而那个孩子具有相同的父对象,我就陷入了循环状态。我正在使用es5,因此没有异步等待。

var visited_nodes = {"5a8c1c966ac6cb3c078fe727" : true};

//this map keep track of visited nodes

function getChildCategories(parentCategory){
return parentCategory.map(child => {
  return new Promise((resolve,reject) => {
  if(!visited_nodes[child]){
    Taxonomy.findOne({_id : child}).then((resp) => {
       visited_nodes[child] = true;
       console.log(resp.children);
       if(resp.children && resp.children.length > 0){
           getChildCategories(resp.children)
           .map(x => x).then(childresp => {
               resp.children = childresp;
               resolve([resp]);
           })
       }else{
         resp.children = null;
         resolve(resp);
       }
    }).catch(err => {
        reject(err);
    });
   }else{
       console.log("already visited")
       return resolve({});
   }
  });
});
};

由于异步DB调用,很难创建树,因为map函数在异步调用中返回null。任何人都有关于如何执行此操作的解决方案

1 个答案:

答案 0 :(得分:0)

您似乎正在寻找

function getCategory(category) {
  if (visited_nodes[category]) {
    console.log("already visited")
    return Promise.resolve({});
  }
  visited_nodes[category] = true;
  return Taxonomy.findOne({_id : category}).then(resp => {
    return getChildCategories(resp.children).then(children =>
      resp.children = children;
      return resp;
    });
  });
}
function getChildCategories(children) {
  console.log(children);
  if (children && children.length > 0) {
    return Promise.all(children.map(getCategory));
  } else {
    return Promise.resolve(null);
  }
}