具有多个mongoose find的foreach循环后的javascript承诺
我正在尝试与一些db调用进行循环,一旦它们全部完成,我将发送结果。-使用承诺,但如果我在回调后得到承诺,它就不起作用了具有多个mongoose find的foreach循环后的javascript承诺,javascript,node.js,mongoose,promise,Javascript,Node.js,Mongoose,Promise,我正在尝试与一些db调用进行循环,一旦它们全部完成,我将发送结果。-使用承诺,但如果我在回调后得到承诺,它就不起作用了 let notuser = []; let promise = new Promise((resolve, reject) => { users.forEach((x) => { User.find({ /* query here */ }, function(err, results) { if(e
let notuser = [];
let promise = new Promise((resolve, reject) => {
users.forEach((x) => {
User.find({
/* query here */
}, function(err, results) {
if(err) throw err
if(results.length) {
notuser.push(x);
/* resolve(notuser) works here - but were not done yet*/
}
})
});
resolve(notuser); /*not giving me the array */
}).then((notuser) => {
return res.json(notuser)
})
我该如何处理这个问题呢?我建议您看看这是一个非常适合这类事情的库,我真的认为您应该习惯于实现它 我将使用以下方法解决您的问题
const async = require('async')
let notuser = [];
async.forEach(users, (user, callback)=>{
User.find({}, (err, results) => {
if (err) callback(err)
if(results.length) {
notUser.push(x)
callback(null)
}
})
}, (err) => {
err ? throw err : return(notuser)
})
但是,如果您不想使用第三方库,最好使用promise.all并等待它完成
编辑:记住使用
npm
或warn
类似于warn add async
的东西来安装async
,npm install async
下面是一个名为findManyUsers
的函数,它可以满足您的需求。Mongo find将向您返回一个承诺,因此只需在循环中收集这些承诺并与promise.all()
一起运行即可。所以您可以看到它的实际应用,我添加了一个模拟用户类,其中包含一个承诺返回find方法
//用户类假装是mongo用户。find()方法
//返回“查找”具有给定id的用户的承诺
类用户{
静态查找(id){
返回新承诺(r=>{
setTimeout(()=>r({id:`user-${id}`}),500);
});
}
}
//返回查找具有给定ID的所有用户的承诺
异步函数findManyUsers(ID){
让promises=ids.map(id=>User.find(id));
返回承诺。全部(承诺);
}
findManyUsers(['A','B','C'])。然后(result=>console.log(result));
我在我的场景中使用@danh解决方案作为修复的基础(因此值得称赞),但我认为我的代码可能与其他人有关,希望在不使用异步的情况下使用标准mongoose。我想获得某个状态的报告数量的摘要,并返回每个状态的最后5个报告,合并到一个响应中
const { Report } = require('../../models/report');
const Workspace = require('../../models/workspace');
// GET request to return page of items from users report
module.exports = (req, res, next) => {
const workspaceId = req.params.workspaceId || req.workspaceId;
let summary = [];
// returns a mongoose like promise
function addStatusSummary(status) {
let totalItems;
let $regex = `^${status}$`;
let query = {
$and: [{ workspace: workspaceId }, { status: { $regex, $options: 'i' } }],
};
return Report.find(query)
.countDocuments()
.then((numberOfItems) => {
totalItems = numberOfItems;
return Report.find(query)
.sort({ updatedAt: -1 })
.skip(0)
.limit(5);
})
.then((reports) => {
const items = reports.map((r) => r.displayForMember());
summary.push({
status,
items,
totalItems,
});
})
.catch((err) => {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
});
}
Workspace.findById(workspaceId)
.then((workspace) => {
let promises = workspace.custom.statusList.map((status) =>
addStatusSummary(status)
);
return Promise.all(promises);
})
.then(() => {
res.status(200).json({
summary,
});
})
.catch((err) => {
if (!err.statusCode) {
err.statusCode = 500;
}
next(err);
});
};
映射查询承诺数组并使用
Promise.all()
err?throw err:return(notuser)在异步回调中没有意义我只是按照他的逻辑,他想在错误存在时抛出一个错误。我的示例的目标是向异步回调的用户展示