我有一个简单的功能:
const oldUsers = Users.find(
{
isReminded: false,
creationDate: {
"$lt": new Date(Date.now() - thirtyDays),
},
},
);
然后:
export const notifyOldUsers = () =>
Array.isArray(oldUsers) ? oldUsers.map(async(user, i) => {
await Users.updateOne({ _id: user._id }, { "$set": { isReminded: true }});
await transporter.sendMail(sendMail));
}) : [];
};
但是问题是oldUsers
返回对象,如果我console.log
返回,则它是一个复杂的Query
对象。
问题:如何正确循环.find()
产生的数据?
答案 0 :(得分:1)
首先,Users.find()
是一个异步操作,因此oldUsers
始终是不确定的。您需要await
(如果您没有使用promise,则必须使用回调)。
const oldUsers = await Users.find(...)
第二,您的notifyOldUsers
函数不是异步的,因此它运行映射函数,但是会立即退出,而不是等待映射的异步操作完成。
通常,在映射异步操作时,您应该使用Promise.all()
来收集回调函数返回的所有promise,并等待它们全部解决。
export const notifyOldUsers = async () => {
const promises = oldUsers.map(async (user) => {
await Users.updateOne({ _id: user._id }, { "$set": { isReminded: true }})
await transporter.sendMail(sendMail))
})
return Promise.all(promises)
}
我特意从Promise.all()
拆分了映射,以说明返回的诺言图。可以对此进行进一步优化。
export const async notifyOldUsers = async () => {
return Promise.all( oldUsers.map(async (user) => {
await Users.updateOne({ _id: user._id }, { "$set": { isReminded: true }})
await transporter.sendMail(sendMail))
}) )
}
在两种情况下,此异步函数都会返回一个新的promise,其值将是一个包含整个映射结果的数组。