Как использовать обещания для возврата массива объектов, которые рекурсивно редактируются в экспресс-маршрутизаторе в nodejs? - PullRequest
1 голос
/ 03 июня 2019

Я пытаюсь вернуть массив объектов узлов, каждый из которых имеет уникальную метку и массив дочерних узлов, каждый из которых идентифицируется своей уникальной меткой, для использования в моем интерфейсе с компонентом дерева (https://reactjsexample.com/a-simple-react-tree-menu-component/).Категория - это список mongodb с родительской меткой, дочерним массивом дочерних меток, их собственной уникальной меткой и номером.

Запуск функции createTreeJson без обещания и печать treeData после задержки выводит правильный результат.Я пытался преобразовать recursiveCat для возврата обещания и ставить .then после каждого вызова recursiveCat:

recursiveCat(node.nodes, category.label, indexC).then(() => resolve()); 

, но это никогда не завершало вызов API. Я очень плохо знаком с обещаниями, и они меня смущают, несмотря на некоторыеисследование.

router.get("/tree", (req, res) => {
var treeData= [];
createTreeJson(treeData).then(() => res.json(treeData));
function createTreeJson(treeData){
    return new Promise(resolve => {
        Category.find({ level: 0 }).then( categories => {
            categories.forEach((category) => {
              var node = {
                key: category.label,
                label: category.label,
                index: treeData.length,
                nodes: []
              }
              treeData.push(node);
              recursiveCat(node.nodes, category.label, treeData.length);
              resolve();
            });
          });
    })
}
function recursiveCat(nodes, parLabel, indexC){
  console.log("cat call")
    Category.find({ parent: parLabel }).then( categories => {
      categories.forEach((category) => {
        //console.log(category.children.length)
        var node = {
          key: category.label,
          label: category.label,
          index: indexC,
          nodes:  []
        }
        nodes.push(node);
        recursiveCat(node.nodes, category.label, indexC);
      })
    })
  }
})

Результат:

[
    {
        "key": "Video Games",
        "label": "Video Games",
        "index": 0,
        "nodes": []
    },
    {
        "key": "Sports",
        "label": "Sports",
        "index": 1,
        "nodes": []
    }
]

Ожидается (генерируется из того же кода, но без обещаний и печатается с задержкой и только в виде спорта, показанных в качестве примера):

{ key: 'Sports',
  label: 'Sports',
  index: 1,
  nodes:
   [ { key: 'Basketball', label: 'Basketball', index: 2, nodes: [] },
     { key: 'Combat Sports',
       label: 'Combat Sports',
       index: 2,
       nodes: [] },
     { key: 'Soccer', label: 'Soccer', index: 2, nodes: [] },
     { key: 'Tennis', label: 'Tennis', index: 2, nodes: [] },
     { key: 'Track', label: 'Track', index: 2, nodes: [] },
     { key: 'Volleyball', label: 'Volleyball', index: 2, nodes: [] },
     { key: 'Football', label: 'Football', index: 2, nodes: [] },
     { key: 'Hockey', label: 'Hockey', index: 2, nodes: [] },
     { key: 'Golf', label: 'Golf', index: 2, nodes: [] },
     { key: 'Rugby', label: 'Rugby', index: 2, nodes: [] } ] }

Любая помощь приветствуется, спасибо! Это первый вопрос, который я задал, так что, если я задал неправильно или янедостающая информация, дайте мне знать!

Ответы [ 2 ]

0 голосов
/ 03 июня 2019

Попробуйте следующий код, пожалуйста.

var treeData= [];
createTreeJson(treeData).then((r) => res.json(r));
function createTreeJson(treeData){
    return Category.find({ level: 0 }).then( categories => {
        return Promise.all(
            categories.map(category => {
                var catArray = {
                    key: category.label,
                    label: category.label,
                    index: treeData.length,
                    nodes: []
                };
                return recursiveCat(node.nodes, category.label, treeData.length).then(
                    r => (catArray.nodes = r, catArray)
                );
            }
        ));
    });
}

function recursiveCat(nodes, parLabel, indexC){
    return Category.find({ parent: parLabel }).then( categories => {
        return Promise.all(categories.map((category) => {
            var catArray = {
                key: category.label,
                label: category.label,
                index: indexC,
                nodes:  []
            };
            return recursiveCat(node.nodes, category.label, indexC).then(
                r => (catArray.nodes = r, catArray)
            );
        }));
    })
}
0 голосов
/ 03 июня 2019

В вашем коде есть 2 проблемы:

  • resolve() похоже на return, вам нужно что-то вставить. Вы должны написать:

    resolve(recursiveCat(node.nodes, category.label, treeData.length))

  • Ваша рекурсивная функция ничего не возвращает.Я думаю, это должно выглядеть примерно так:

function recursiveCat(nodes, parLabel, indexC){
  console.log("cat call");
    Category.find({ parent: parLabel }).then( categories => {
      categories.forEach((category) => {
        var self_node = recursiveCat(node.nodes, category.label, indexC);
        var node = {
          key: category.label,
          label: category.label,
          index: indexC,
          nodes:  self_node
        }
        nodes.push(node);
        
        
      });
      return nodes;
    });
  }
...