我正在尝试对一些数据库调用进行循环,一旦它们全部完成都会发送结果。 -使用promise,但是如果我在回调后有我的promise,它将起作用。
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)
})
我该如何处理?
答案 0 :(得分:1)
下面是一个名为findManyUsers
的函数,它可以满足您的需求。 Mongo find将向您返回一个承诺,因此只需循环收集这些承诺并与Promise.all()
一起运行它们即可。因此,您可以看到它的运行情况,我添加了一个模拟用户类,其中包含一个返回承诺的find方法...
// User class pretends to be the mongo user. The find() method
// returns a promise to 'find" a user with a given id
class User {
static find(id) {
return new Promise(r => {
setTimeout(() => r({ id: `user-${id}` }), 500);
});
}
}
// return a promise to find all of the users with the given ids
async function findManyUsers(ids) {
let promises = ids.map(id => User.find(id));
return Promise.all(promises);
}
findManyUsers(['A', 'B', 'C']).then(result => console.log(result));
答案 1 :(得分:0)
我建议您看看async,它是一个很好的库,可以处理这类事情,而且,我真的认为您应该习惯于实现它。
我将使用以下方法解决您的问题
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并等待它完成。
编辑:记住使用async
或npm
类似于yarn
-yarn add async
npm install async
>
答案 2 :(得分:0)
我使用@danh解决方案作为解决方案的基础(因此值得一提),但我认为我的代码可能与其他人相关,希望使用不带异步的标准猫鼬。我想总结某个状态的报告数量,并返回每个报告的最后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);
});
};