【发布时间】:2016-04-28 07:22:09
【问题描述】:
我有一个等级制度。一个类别有一个 parentid(如果它是根类别,则为 0)。
类别数据库中的示例行:
name | id | parentid
-----------+------+----------
Label | 71 | 8
我需要获取给定类别的所有子类别。 all 不仅是指一个类别的直接子代,而且是所有子代的每个子代。
我以前做过递归的东西,但在同步环境中,它的工作方式并不完全相同。
我知道我离一个可行的解决方案不远了,但它并不适用于所有情况。注意:删除了所有调试日志行,以免问题混乱。
此外,欢迎进行任何简化和/或优化。例如,我不喜欢有两个回调,一个是递归的,一个是最后一个......(但可能由于异步,它需要这样?)。
整个事情应该返回给定类别的所有子类别的 id 数组 (allCats)。
当前的解决方案适用于没有子级的单个类别,并且层次结构向下一层(并且allCats 正确包含所有 ID)。在两个级别上它都失败了(最终的回调永远不会被调用,所以cnt 没有被正确更新?)。
调用Category.getAllSubCategories(categoryId);开始搜索
Category.getSubCategories = function(cat, cnt, fullCats, cb, finalCb) {
Category.find({where: {parentId: cat.id}}, function(err, cats) {
if (err) {
cb(err);
}
if (cats.length > 0) {
var ids = [];
for (var i=0; i<cats.length; i++) {
ids.push(cats[i].id);
}
fullCats = fullCats.concat(ids);
cb(null, cnt, fullCats, cats, finalCb);
} else {
if (cnt > 0) cnt -= 1;
cb(null, cnt, fullCats, null, finalCb);
}
});
}
var catSearchCallback = function(err, cnt, fullCats, cats, finalCb) {
if (err) {
finalCb(err);
}
if (cats) {
for (var c=0; c<cats.length; c++) {
cnt += 1;
Category.getSubCategories(cats[c], cnt, fullCats, catSearchCallback, finalCb);
}
} else {
if (cnt == 0) {
finalCb(null, fullCats);
}
}
}
/* start here */
Category.getAllSubCategories = function(categoryId, cb) {
Category.findById(categoryId, function(err, cat) {
if (err) {
return logger.error(err);
}
var fullCats = []; //collection holding ALL ids
var cnt = 0; //counter to count how many steps we have done
if (cat) {
fullCats.push(categoryId); //the category in question needs to be in the results as well
Category.getSubCategories(cat, cnt, fullCats, catSearchCallback, function(err, allCats) {
if (err) {
cb(err);
}
cb(null, allCats);
});
} else {
return categoryId;
}
});
}
【问题讨论】:
-
你尝试过使用承诺吗?我简化了所有这些回调的连接......
-
我对 Promises 的掌握太少,无法自己提出一个可行的解决方案......我正在学习它们,但还没有
-
@faboolous 尝试从这里开始:bluebirdjs.com/docs/why-promises.html Promises 将解决这个问题。
标签: javascript asynchronous recursion loopbackjs