Mongoose方法返回undefined

我已经成功地定义和使用我的项目mongoose模型:

const Schema = mongoose.Schema; const Item = new Schema({ name : String, hierarchy: [{ type: Schema.ObjectId, ref: this }], hierarchy_size: Number }); 

在保存之前和之后,我将相应的hierarchy_size和hierarchy值填充到其属性中,使其成为分层树:

 Item.pre("save", function(next) { this['hierarchy_size'] = this.hierarchy.length; next(); }) Item.post('save', (doc, next) => { if ((doc._id) && (doc.hierarchy.length == 0)) { doc.hierarchy = [doc._id]; doc.save(); } next(); }) 

现在我正在为每个根子节点(在查询hierarchy_size == 1之后)运行以下方法getChildren:

 Item.methods.getChildren = function() { this.model("Item").find({hierarchy: this._id, hierarchy_size: this.hierarchy_size+1}).exec(function(err, children){ if(!err){ let childrenHierarchy = []; for(let child of children){ childrenHierarchy.push(child); } return childrenHierarchy; } }) }; 

但是在控制器上,当迭代第一级实例时,我对item.getChildren()的调用返回undefined。

 app.get('/items', (req, res) => { Item.find({hierarchy_size: 1}).exec((err, menus) => { if (err) { res.status(500).json(err.message); } else { let rootTree = [] for(let item of items){ rootTree.push(item.getChildren()); } res.status(200).json(rootTree); } }); }); 

调用item.getChildren方法,方法内部的console.log(this)显示正确的实例数据,childrenHierarchy中填充了适当的子对象,但未定义返回而不是childrenHierarchy内容。 有关为什么发生的任何提示? 我是否正确地使用第一个查询返回的实例?

首先,我会强烈build议你使用Promise,以避免callback噩梦。

答案是最简单的:你正在使用asynchronous函数和普通对象一样,第二,你没有使用getChildren方法返回任何东西。

为了解决您的问题,只需修改您的getChildren为:

 Item.methods.getChildren = function() { return this.model("Item").find({hierarchy: this._id, hierarchy_size: this.hierarchy_size+1}) .exec() .then(result => { let childrenHierarchy = []; for(let child of children){ childrenHierarchy.push(child); } return childrenHierarchy; }) .catch(err => { console.log("the error occured!", err) }) }; 

但是,您还需要修改您的API端点:

 app.get('/items', (req, res) => { Item.find({ hierarchy_size: 1 }) .exec() .then(menus => { let rootTree = [] let promiseChain = Promise.resolve({}); for (let item of menus) { promiseChain = promiseChain.then(() => { return item.getChildren() .then(children => { rootTree.push(children); }) }) } promiseChain.then(() => { res.status(200).json(rootTree); }) }) .catch(err => { res.status(500).json(err.message); }) }); 

这是不可能的,因为你不能从同步方法中的asynchronous调用返回。

你可以做的是,你可以为你的方法传递一个callback函数,像这样:

 Item.methods.getChildren = function(callback) { this.model("Item").find({hierarchy: this._id, hierarchy_size: this.hierarchy_size+1}).exec(function(err, children){ if(!err){ let childrenHierarchy = []; for(let child of children){ childrenHierarchy.push(child); } callback(childrenHierarchy); } }) }; 

或者你可以使用承诺,让你的生活更轻松…