我已成功定义并使用我的项目mongoose模型:
const Schema = mongoose.Schema;
const Item = new Schema({
name : String,
hierarchy: [{ type: Schema.ObjectId, ref: this }],
hierarchy_size: Number
});
在保存前后,我将hierarchy_size和层次结构值相应地填充到它的属性中,使其成为分层树:
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,但返回undefined而不是childrenHierarchy内容。有关它为何发生的任何提示?我是否正常使用第一个查询返回的实例?
答案 0 :(得分:1)
这是不可能的,因为你无法从同步方法中的异步调用返回。
你可以做的是,你可以为你的方法传递一个回调函数,如下所示:
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);
}
})
};
或者你可以使用承诺,让你的生活更轻松......
答案 1 :(得分:1)
首先,我强烈建议你改用Promise,以避免回调噩梦。
答案很简单:你使用async函数和普通对象一样,第二个,你没有使用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);
})
});