NodeJS 异步和递归
NodeJS Asynchronous and Recursive
我进行了广泛的搜索,但找不到似乎可行的答案。我试过 Q.deferred、async.series、async.each,我似乎无法让这个笨蛋工作:
这是代码,它可以工作,但是,"return subTree" 在递归完成之前触发 "tree" 导出。我已经验证递归正在适当地挖掘。我真的需要 recuriveChildren 上的 return 来等待递归调用完成。
exports.tree = function(req, res) {
var tree = {
'name': 'New Account'
};
var methods = {};
methods.recursiveChildren = function(path) {
var subTree = {
'name': path.field.label+":"+path.match+":"+path.value,
'id': path._id,
'parent': path.parent,
'children': []
}
Path.find({parent:path._id}).sort({date_created:1}).exec(function (err,childpaths) {
for ( var z in childpaths ) {
var tmpTree = methods.recursiveChildren(childpaths[z]);
subTree.children.push(tmpTree);
}
});
return subTree;
}
Path.find({parent:null}).sort({date_created:1}).exec(function (err,paths) {
tree.children = [];
for ( var x in paths ) {
var tmpTree = methods.recursiveChildren(paths[x]);
tree.children.push(tmpTree);
}
res.jsonp(tree);
});
};
关于异步模式的令人困惑的事情是你不能 return 实际值,因为那还没有发生。您可以传入异步操作完成后要执行的函数(回调),或者您可以 return 一个接受回调(承诺)的对象,一旦操作解决了承诺,该对象就会执行回调一个值。
exports.tree = function(req, res) {
var tree = {
'name': 'New Account'
};
var methods = {};
methods.recursiveChildren = function(path) {
var subTree = {
'name': path.field.label + ":" + path.match + ":" + path.value,
'id': path._id,
'parent': path.parent,
'children': []
}
return new Promise(function(resolve, reject) {
Path.find({
parent: path._id
}).sort({
date_created: 1
}).exec(function(err, childpaths) {
Promise
.all(childpaths.map(function(childpath) {
/* collect a promise for each child path this returns a promise */
return methods.recursiveChildren(childpath);
}))
.then(function(resolvedPaths) {
subtree.children = resolvedPaths;
/* the top level promise is fulfilled with the subtree */
resolve(subTree);
});
});
});
}
Path.find({
parent: null
}).sort({
date_created: 1
}).exec(function(err, paths) {
Promise.all(paths.map(function(path) {
return methods.recursiveChildren(path);
})).then(function(resolvedPaths) {
tree.paths = resolvedPaths;
res.jsonp(tree);
});
});
};
我进行了广泛的搜索,但找不到似乎可行的答案。我试过 Q.deferred、async.series、async.each,我似乎无法让这个笨蛋工作:
这是代码,它可以工作,但是,"return subTree" 在递归完成之前触发 "tree" 导出。我已经验证递归正在适当地挖掘。我真的需要 recuriveChildren 上的 return 来等待递归调用完成。
exports.tree = function(req, res) {
var tree = {
'name': 'New Account'
};
var methods = {};
methods.recursiveChildren = function(path) {
var subTree = {
'name': path.field.label+":"+path.match+":"+path.value,
'id': path._id,
'parent': path.parent,
'children': []
}
Path.find({parent:path._id}).sort({date_created:1}).exec(function (err,childpaths) {
for ( var z in childpaths ) {
var tmpTree = methods.recursiveChildren(childpaths[z]);
subTree.children.push(tmpTree);
}
});
return subTree;
}
Path.find({parent:null}).sort({date_created:1}).exec(function (err,paths) {
tree.children = [];
for ( var x in paths ) {
var tmpTree = methods.recursiveChildren(paths[x]);
tree.children.push(tmpTree);
}
res.jsonp(tree);
});
};
关于异步模式的令人困惑的事情是你不能 return 实际值,因为那还没有发生。您可以传入异步操作完成后要执行的函数(回调),或者您可以 return 一个接受回调(承诺)的对象,一旦操作解决了承诺,该对象就会执行回调一个值。
exports.tree = function(req, res) {
var tree = {
'name': 'New Account'
};
var methods = {};
methods.recursiveChildren = function(path) {
var subTree = {
'name': path.field.label + ":" + path.match + ":" + path.value,
'id': path._id,
'parent': path.parent,
'children': []
}
return new Promise(function(resolve, reject) {
Path.find({
parent: path._id
}).sort({
date_created: 1
}).exec(function(err, childpaths) {
Promise
.all(childpaths.map(function(childpath) {
/* collect a promise for each child path this returns a promise */
return methods.recursiveChildren(childpath);
}))
.then(function(resolvedPaths) {
subtree.children = resolvedPaths;
/* the top level promise is fulfilled with the subtree */
resolve(subTree);
});
});
});
}
Path.find({
parent: null
}).sort({
date_created: 1
}).exec(function(err, paths) {
Promise.all(paths.map(function(path) {
return methods.recursiveChildren(path);
})).then(function(resolvedPaths) {
tree.paths = resolvedPaths;
res.jsonp(tree);
});
});
};