gpt4 book ai didi

javascript - 批量发送电子邮件并捕获不成功的尝试

转载 作者:可可西里 更新时间:2023-11-01 10:01:38 26 4
gpt4 key购买 nike

前端代码包含一个名称列表,每个名称旁边都有复选框。目标是向所有选中的名称发送一封电子邮件。单击提交按钮后,一组 ID(针对每个用户)将发送到我的后端。

后端代码查询数据库(使用 mongoose odm 的 mongo)并找到用户。我有一些任务需要在后端完成:

  • 找到具有提供的 ID 数组的用户
  • 创建并向每个用户发送电子邮件
  • 如果电子邮件发送成功,则更新发送电子邮件的数据库中的文档字段
  • 如果电子邮件失败,将用户名发送回前端以通知“发件人”电子邮件尝试失败。

我编写这段代码的时间比我愿意承认的要长......这是我目前所拥有的(我关心的是后端代码):

exports.sendEmailToUsers = function (req, res, next) {
mongoose.model('SpendingReport').find({ _id: { $in: req.body.recipientIds } }).populate('report user')
.find({ 'report.emailedReport': { $exists: false } }) // this needs to be refined for dev, new reports will have an emailedGradePost property
.then(spendingReports => {
return Bluebird.map(spendingReports, spendingReport => {
const email = new Email({ email: spendingReport.user.email, name: spendingReport.user.fullName }, {})

return email.send()
.then(() => {
spendingReport.report.update({ emailedReport: new Date() })
// I don't need anything returned if it is successful, this feels weird though, map doesn't
// seem like the correct function to use.

// return {spendingReport.report.emailedGradePost}
})
.catch(e => {
// I am catching each email's error so I know which email failed
return { error: e, user: spendingReport.user.fullName }
});
});
})
.then(unsuccessfulAttempts => {
// the array has the error obect from the .catch and also undefined values for the successful attempts
console.log(unsuccessfulAttempts);
})
.then(() => {
res.sendStatus(200); // filler status for now
})
.catch(e => {
console.log(e);
});
};

这是我的问题:

  • 我正在使用 Bluebird.map,感觉有点代码味。理论上,我可以在 spendingReports 数组上使用 .map,该数组包含数据库中的文档数组,并使用每个 spendingReport< 中的信息创建一封电子邮件。问题是,当我将电子邮件返回到 promise 链中的下一个 .then() 时,我将无法访问 spendingReport 对象,例如
exports.sendEmailToUsers = function (req, res, next) {
mongoose.model('SpendingReport').find({ _id: { $in: req.body.recipientIds } }).populate('report user')
.find({ 'report.emailedReport': { $exists: false } }) // this needs to be refined for dev, new reports will have an emailedGradePost property
.then(spendingReports => {
return spendingReports.map(spendingReport => new Email({ email: spendingReport.user.email, name: spendingReport.user.fullName }, {}));
// {email: email, spendingReport: spendingReport} I might need this format instead, referenect the note
// in the next promise chain.
})
.then(emails => {
return Bluebird.map(emails, email => {
email.send()
.then(() => {
// Note: I lost access to "spendingReport", I would need to pass this object
// with each email object {email: email, spendingReport: spendingReport}
spendingReport.report.update({ emailedReport: new Date() })
.catch(e => {
return { error: e, user: spendingReport.user.fullName };
})
})
})
})
.then(unsuccessfulAttempts => {

console.log(unsuccessfulAttempts);
})
.then(() => {
res.sendStatus(200); // filler status for now
})
.catch(e => {
console.log(e);
});
};
  • 我有一个嵌套的 promise 链(在 Bluebird.map 内部,发送电子邮件,然后将其保存到成功的数据库中)。我知道嵌套 promise 是一种反模式。减轻嵌套 promise 的唯一方法是在每个 .then 中传递与每个电子邮件关联的文档对象,与仅在 中具有嵌套 promise 链相比,这感觉更像是一种负担 bluebird map

  • 我不知道当电子邮件发送成功并成功保存时,在 Bluebird.map 中返回什么。现在我没有返回任何东西,所以 undefined 被返回。

  • 理想情况下,我可以并行发送所有电子邮件,例如 Promise.all([email.send(), email.send(), email.send()]),然而,这使得将电子邮件成功保存到数据库更具挑战性(我需要再次访问 spendingReports 文档并更新 report,这感觉就像很多查询)。

最佳答案

使用 async-await 可以减少你的问题(因为你可以通过索引获取所有项目)

async function(req, res, next) {
let spendingReports = await mongoose.model('SpendingReport').find(...)
let emails = spendingReports.map(r=>new Email(...))
let sendingmails = emails.map(e=>e.send())
let success=[],fail=[];
await Promise.all(sendingmails.map((s,i)=>s.then(_=>success.push(i)).cache(_=>fail.push(i))))

//now you have index of success and failed mails.
//just process these data and do whatever you want
}

中间数据不是必需的,像这样一行(不要真的这样做)

async function(req, res, next) {
let success=[],fail=[];
await Promise.all(await mongoose.model('SpendingReport').find(...).then(spendingReports => spendingReports.map(r=>(new Email(...)).send().then(_=>success.push(r)).cache(_=>fail.push(r))))

//now you have success and failed spendingReports.
//just process these data and do whatever you want
}

关于javascript - 批量发送电子邮件并捕获不成功的尝试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55882130/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com