【发布时间】:2019-08-06 05:16:22
【问题描述】:
我想收集数据及其子项(绑定到该产品 ID 的另一项) 我有一个具有此架构的集合
// User Schema
const filtersSchema = mongoose.Schema({
filter_name:{
type: String,
required: true
},
filter_code:{
type: String,
required: true,
unique: true
},
bind_to: {
type: Schema.Types.ObjectId,
default: null
},
filter_status:{
type: Boolean,
default: true
},
created_on:{
type: Date,
default: Date.now
},
updated_on:{
type: Date,
default: Date.now
}
});
如果我向它输入数据,默认的 bind_to 值将为空,这意味着它的父级。如果我发送父级的 bind_to ID,它将是 ObjectID。
我想收集这样的数据
[{
-- parent object --
children:[
{
-- child object --
},
{
-- child object --
}
]
}]
如果我们有多个项目,它将通过循环 (forEach),但回调是在 forEach 循环完成之前发送的。我知道 forEach 是异步的,请求是同步的。但对如何做到这一点感到困惑!
你可以看到下面的模块
// Get Filters by Parent ID
module.exports.getFiltersByParentId = (pid, callback) => {
Filters.find({bind_to: pid}, callback);
}
//For getting the parent object and looping it to get its child objects
module.exports.getFilters = (callback, limit) => {
Filters.find({bind_to: null}, (err, filters) => {
if (err) {
console.log(err);
let obj = {status: false, error: err.errmsg};
callback(obj);
} else {
const resObj = [];
filters.forEach(async function (ele) {
await Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resObj.push(ele);
}
});
});
Promise.all(resObj).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
}
});
}
但在这种情况下,结果对象将为空。如何获得具有上述值的正确对象?
即使我尝试过这种方法
const resObj = [];
filters.map(function (ele) {
Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resObj.push(ele);
}
});
});
Promise.all(resObj).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
还有这个
Promise.all(filters.map(function (ele) {
Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resObj.push(ele);
}
});
})).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
好的,现在我从getFiltersByParentId返回一个承诺
module.exports.getFiltersByParentId = (pid, callback) => {
return new Promise(function(resolve, reject) {
Filters.find({bind_to: pid}, function (err, results) {
if (err) {
reject(err);
} else {
resolve(results);
}
})
});
}
【问题讨论】:
-
I know forEach is asynchronous and the request is synchronous正好相反。 -
您正在尝试在
forEach中使用await-forEach行将在异步操作完成之前完成,因此resObj为空。请改用.map -
你需要返回一个Promise,现在映射的数组只是
undefineds,查看如何将回调API转换为promise -
应该
callback(obj)在if (err) {块中终止处理,还是callback在错误和成功的情况下期望被多次调用
标签: node.js express mongoose promise