Mongooseasynchronous调用内循环与asynchronous库

我刚开始使用nodejs / mongoose,我想我有一个经典的asynchronous问题。 有人可以指导我如何解决这个asynchronous问题?

我有这个函数“getAreasRoot”和里面我有一个循环来填充另一个asynchronous函数的结果的儿童。 我怎样才能解决它与asynchronous库?

areaSchema.statics.getAreasRoot = function(cb: any) { let self = this; return self.model("Area").find({ parentId: null }, function(err: any, docs: any){ docs.forEach(function(doc: any){ doc.name = "Hi " + doc.name; doc.children = self.model("Area").getAreasChildren(doc._id, function(err: any, docs: any){}); }) cb(err, docs); }); }; areaSchema.statics.getAreasChildren = function(id: any, cb: any) { return this.model("Area").find({ parentId: null }).exec(cb); } 

你有2个任务:得到根,然后让根子的孩子。

如果我使用async.js来做这个,我会使用async.waterfall和async.mapSeries的组合。 我们使用.waterfall因为我们想把第一个任务的结果传给第二个任务。 我们使用.mapSeries因为我们想要改变每个根区域的名称和子级。

 areaSchema.statics.getAreasRoot = function (cb) { let self = this; async.waterfall([ // every task has a callback that must be fired at least/most once // to tell that the task has finished OR when an error has occurred function getRoots (cb1) { self.find({ parentId: null }, cb1); }, function getChildren (roots, cb2) { async.mapSeries(roots, function (root, cb3) { // inside this block, we want to fire the innest callback cb3 when // each iteration is done OR when an error occurs to stop .mapSeries self.find({ parentId: root._id }, function (err, children) { // error: stop .mapSeries if (err) return cb3(err); root.name = "Hi " + root.name; root.children = children; // done: send back the altered document cb3(null, root); }); // the last argument is fired when .mapSeries has finished its iterations // OR when an error has occurred; we simply pass the inner callback cb2 }, cb2) } // the last argument is fired when .waterfall has finished its tasks // OR when an error has occurred; we simply pass the original callback cb ], cb); }; 

使用它

 Area.getAreasRoot(function (err, areas) { console.log(err, areas); }) 

在旁边

Mongoose操作是asynchronous的,所以

 doc.children = self.model("Area").getAreasChildren(...) 

是不正确的,因为你正在返回一个反对实际文件的承诺。

可以通过虚拟人口或聚合来简化您的逻辑。