函数中组合异步函数循环"/>
node.js / express / mongoose在异步函数中组合异步函数循环
我正在使用Node.js和猫鼬来获取数据。在发送结果之前,我想遍历数据并获取另一个猫鼬集合的一些其他信息。
我不让它管理,第一个猫鼬呼叫等待,其他诺言完成。我认为我的诺言和.then调用的混合是一团糟...:S
我的代码:
exports.checkChats = (req, res, next) => {
console.log(req.userData.userId);
let modifiedChats = [];
let partner;
Messages.find({ $or: [{ "users.starter": req.userData.userId }, { "users.partner": req.userData.userId }] })
.then(chats => {
if (chats) {
console.log('Start');
const promises = chats.map(async chat => {
if (chat.users.starter.toString() === req.userData.userId.toString()) {
console.log('fetch partnerData for partner ' + chat.users.partner);
partner = chat.users.partner;
}
if (chat.users.partner.toString() === req.userData.userId.toString()) {
console.log('fetch partnerData for starter ' + chat.users.starter);
partner = chat.users.starter;
}
User.findById(partner).then(fetchedPartner => {
console.log('Partner fetched: ', fetchedPartner.userName);
modifiedChats.push({ id: chat._id, status: chat.status, lastMessage: chat.lastMessage, partnerName: fetchedPartner.userName, partnerImg: fetchedPartner.imagePath });
});
});
Promise.all(promises).then(() => {
console.log('End');
res.status(201).json({
message: 'Chats found',
chats: modifiedChats
});
});
}
}).catch(error => {
res.status(500).json({
message: 'Couldnt fetch chats!',
error: error
});
});
};
和终端日志:
Start
fetch partnerData for partner 5eb8502aad51b72012a2ccd1
fetch partnerData for partner 5eb84c93ad51b72012a2cc56
End
Partner fetched: Summer
Partner fetched: Pepe
谢谢你们。
回答如下:您的代码中的问题是这些代码段
const promises = chats.map(async chat => {
if (chat.users.starter.toString() === req.userData.userId.toString()) {
console.log('fetch partnerData for partner ' + chat.users.partner);
partner = chat.users.partner;
}
if (chat.users.partner.toString() === req.userData.userId.toString()) {
console.log('fetch partnerData for starter ' + chat.users.starter);
partner = chat.users.starter;
}
User.findById(partner).then(fetchedPartner => {
console.log('Partner fetched: ', fetchedPartner.userName);
modifiedChats.push({ id: chat._id, status: chat.status, lastMessage: chat.lastMessage, partnerName: fetchedPartner.userName, partnerImg: fetchedPartner.imagePath });
});
});
此循环的每次迭代都调用User.findById(partner)
,它返回一个Promise,并且是异步的。该函数并不知道它需要等待其结果。告诉函数等待User.findById(partner)
完成的一种方法是添加return
。
return User.findById(partner).then(fetchedPartner => {
console.log('Partner fetched: ', fetchedPartner.userName);
modifiedChats.push({ id: chat._id, status: chat.status, lastMessage: chat.lastMessage, partnerName: fetchedPartner.userName, partnerImg: fetchedPartner.imagePath });
});
您也可以删除异步输入
const promises = chats.map(async chat => {
没有用,因为仍然没有利用async/await
。
这里还是使用async/await
重构代码的示例。
exports.checkChats = async (req, res, next) => { // by putting async here, you are enabling a function to use await
try {
console.log(req.userData.userId);
let partner;
const chats = await Messages.find({ $or: [{ "users.starter": req.userData.userId }, { "users.partner": req.userData.userId }] }); // by putting await before a function call the returns a promise, you will have the access to the value it will return by this syntax
console.log('Start');
const promises = chats.map(async chat => { // by putting async here, you are enabling a function to use await; This is also a function so you will need to put async here if you want to use await inside
if (chat.users.starter.toString() === req.userData.userId.toString()) {
console.log('fetch partnerData for partner ' + chat.users.partner);
partner = chat.users.partner;
}
if (chat.users.partner.toString() === req.userData.userId.toString()) {
console.log('fetch partnerData for starter ' + chat.users.starter);
partner = chat.users.starter;
}
const fetchedPartner = await User.findById(partner); // same here, I put await because its a promise
console.log('Partner fetched: ', fetchedPartner.userName);
return { id: chat._id, status: chat.status, lastMessage: chat.lastMessage, partnerName: fetchedPartner.userName, partnerImg: fetchedPartner.imagePath }; // I am just returning the values here, by the end of the .map() it will have created an array of promises that each resolves these objects
});
const modifiedChats = await Promise.all(promises); // this will convert the array of promises to an array of the values that was resolve by each of the promises.
console.log('End');
res.status(201).json({
message: 'Chats found',
chats: modifiedChats
});
} catch (error) { // using try catch the way of catching reject thrown errors / rejected promises
res.status(500).json({
message: 'Couldnt fetch chats!',
error: error
});
}
};
更多推荐
node.js / express / mongoose在异步函数中组合异步函数循环
发布评论