Я пытаюсь вернуть массив объектов узла, каждый из которых имеет уникальную метку и массив дочерних узлов, каждый из которых идентифицируется своей уникальной меткой, для использования в моем интерфейсе с компонентом дерева (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.info("cat call")
Category.find({ parent: parLabel }).then( categories => {
categories.forEach((category) => {
//console.info(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: [] } ] }
Любая помощь приветствуется, спасибо! Это первый вопрос, который я задал, поэтому, если я задал неправильно или у меня нет информации, дайте мне знать!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В вашем коде 2 проблемы:
resolve() похож на return, вам нужно что-то вставить. Вы должны написать:
resolve(recursiveCat(node.nodes, category.label, treeData.length))
Ваша рекурсивная функция ничего не возвращает. Я думаю, что это должно выглядеть примерно так:
function recursiveCat(nodes, parLabel, indexC){
console.info("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;
});
}Попробуйте следующий код, пожалуйста.
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)
);
}));
})
}
Спасибо! Это сработало. Мне нужно изучить Promise.all и .map.
Спасибо за ответ. У меня это работает с решением pindev, но я заставлю и ваше работать, просто чтобы лучше понять, как оно работает.