我想与其子项(与该产品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值为null,表示其父级。如果我发送父母的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);
}
})
});
}
答案 0 :(得分:1)
首先,由于Filters.getFiltersByParentId
不返回承诺,因此await
做出回应毫无意义-因此,我将其包装在新的Promise中-如果有时间,可能会更简单无需担心async / await的方法,因为除了没有引入使用async / await的诺言外,代码中实际上没有任何诺言
仍然,我认为代码更容易阅读,因此,让我们保持异步/等待和承诺主题
第二,使用for ... of
循环使代码非常简单,特别是因为您希望任何错误都可以停止对Filters.getFiltersByParentId
的进一步调用
代码如下
module.exports.getFilters = (callback, limit) => {
Filters.find({bind_to: null}, async (err, filters) => {
if (err) {
console.log(err);
let obj = {status: false, error: err.errmsg};
callback(obj);
} else {
const resObj = [];
for (const ele of filters) {
try {
let result = await new Promise((resolve, reject) => {
Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
reject(obj);
} else {
console.log(ele, "Obj");
ele.children = cfil;
resolve(ele);
}
});
});
resObj.push(result);
} catch(e) {
return callback(obj);
}
}
let obj = {status: true, data: resObj, message: "Filters found"};
callback(obj);
}
});
};
编辑:我有时间:p
这是没有异步/等待的代码,因为没有承诺
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 = [];
const getFilters = (index) => {
if (index < filters.length) {
const ele = filters[index];
Filters.getFiltersByParentId(ele._id, (err, cfil) => {
if (err) {
let obj = {status: false, message: err.errmsg};
callback(obj);
return;
} else {
console.log(ele, "Obj");
ele.children = cfil;
getFilters(index + 1);
}
});
} else {
let obj = {status: true, data: resObj, message: "Filters found"};
callback(obj);
}
};
getFilters(0);
}
});
};
答案 1 :(得分:0)
对问题进行了一些更改并使用@Jaromanda X's和@CertainPerformance指南后,我想出了一个解决问题的方法。它不完全符合我的要求,但输出却完全相同。
我将g Filters.getFiltersByParentId
方法更改为返回Promise
module.exports.getFiltersByParentId = (pid, callback) => {
return new Promise(function(resolve, reject) {
Filters.find({bind_to: pid._id}, function (err, results) {
if (err) {
reject(err);
} else {
let obj = {parent: pid, children: results};
resolve(obj);
}
})
});
}
然后将forEach
更改为array.map
,并在Promise.all
函数中使用了promise数组
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 = [];
var promises = [];
filters.map(function (ele) {
promises.push(Filters.getFiltersByParentId(ele, (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(promises).then(res => {
let obj = {status: true, data: res, message: "Filters found"};
callback(obj);
});
}
});
}
最后,我的输出看起来像这样
[
{
parent: {
--- parent object ---
},
children: [
{
--- child object 1 ---
},
{
--- child object 2 ---
},
{
--- child object n ---
}
]
}
]