如何通过nodemailer同步发送邮件?
How to synchronously send mails through nodemailer?
我正在使用带有 nodemailer 模块的 nodejs 创建一个应用程序来发送邮件。
我的应用程序的过程是读取包含姓名和电子邮件的列表,使用 jimp(基于每个姓名和电子邮件)创建 png 文凭文件,并通过 nodemailer 存储和发送每个文件到每个文件不同的邮件地址,完成后我想删除每个文件,但所有这些都是同步的,因为 png 文凭和发送电子邮件需要一些时间:
我的列表语法是:
const list = [
[name1, email1@mail.com]
[name2, email2@mail.com]
[ ... ]
[namex, emailx@mail.com]
]
实际上我想等待每封邮件发送完毕,因为 gmail 似乎无法同时处理多封邮件,发送 13 或 15 封邮件后显示下一个错误:
error: { Error: Data command failed: 421 4.7.0 Temporary System Problem. Try again later (10). x12sm4645987otk.1 - gsmtp
因此,为了实现这一点,我使用经典的 for 循环遍历列表(foreach 循环以异步方式执行,并且不允许我控制文凭生成),我处理
的每一个位置
//Iterating over mails array
for (let i = 0; i < list.length; i++) {
// Little msg to know what is going on
console.log(`Processing address ${i} out of ${list.length}`)
const element = list[i]
// diplomaData is an object which contains data needed (such as name, course, etc) to create the diploma
diplomaData.name = element[0];
// diplomaDir is the address in which each diploma gets stored, it is returned by the generateDiploma function
diplomaDir = await generator.generateDiploma(diplomaData)
// So once the diploma is generated, I send its address to generateMailContentFunction
// it returns an object which contains text like a greeting, congratulations and of course, the diploma address
mailContent = await mailer.generateMailContent(element, diplomaDir)
// So the only thing pending is to send the email with the correspondent content
await mailer.sendMail(mailContent)
// I've commented this function because even it is declared in an async way it
// await utilities.remove(diplomaDir)
}
这是我的 sendMail 函数:
exports.sendMail = async (mailOptions) => {
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log("error: ", err);
} else {
console.log(`Mail sent succesfully!`);
}
});
}
所以简而言之,我的问题是 nodemailer 似乎在完成循环后同时启动所有邮件(我可以确认这一点,因为在我的控制台中,"Processing address ..." 的日志出现在来自nodemailer,所以我只想让这个过程绝对同步,有人可以帮我吗?:(
您的 sendMail 函数本质上不是异步的。它正在启动一个异步函数(即 transporter.sendMail
),然后立即 returning undefined
(因为没有 return 语句)。
exports.sendMail = function(mailOptions){
return new Promise(function (resolve, reject){
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log("error: ", err);
reject(err);
} else {
console.log(`Mail sent successfully!`);
resolve(info);
}
});
});
}
现在,当您 await mailer.sendMail(mailContent)
承诺将 returned 并且实际上会有一些等待。也就是承诺的决议或者拒绝。
确保有一个 try/catch 块包含所有 await 运算符。
我正在使用带有 nodemailer 模块的 nodejs 创建一个应用程序来发送邮件。
我的应用程序的过程是读取包含姓名和电子邮件的列表,使用 jimp(基于每个姓名和电子邮件)创建 png 文凭文件,并通过 nodemailer 存储和发送每个文件到每个文件不同的邮件地址,完成后我想删除每个文件,但所有这些都是同步的,因为 png 文凭和发送电子邮件需要一些时间:
我的列表语法是:
const list = [
[name1, email1@mail.com]
[name2, email2@mail.com]
[ ... ]
[namex, emailx@mail.com]
]
实际上我想等待每封邮件发送完毕,因为 gmail 似乎无法同时处理多封邮件,发送 13 或 15 封邮件后显示下一个错误:
error: { Error: Data command failed: 421 4.7.0 Temporary System Problem. Try again later (10). x12sm4645987otk.1 - gsmtp
因此,为了实现这一点,我使用经典的 for 循环遍历列表(foreach 循环以异步方式执行,并且不允许我控制文凭生成),我处理
的每一个位置//Iterating over mails array
for (let i = 0; i < list.length; i++) {
// Little msg to know what is going on
console.log(`Processing address ${i} out of ${list.length}`)
const element = list[i]
// diplomaData is an object which contains data needed (such as name, course, etc) to create the diploma
diplomaData.name = element[0];
// diplomaDir is the address in which each diploma gets stored, it is returned by the generateDiploma function
diplomaDir = await generator.generateDiploma(diplomaData)
// So once the diploma is generated, I send its address to generateMailContentFunction
// it returns an object which contains text like a greeting, congratulations and of course, the diploma address
mailContent = await mailer.generateMailContent(element, diplomaDir)
// So the only thing pending is to send the email with the correspondent content
await mailer.sendMail(mailContent)
// I've commented this function because even it is declared in an async way it
// await utilities.remove(diplomaDir)
}
这是我的 sendMail 函数:
exports.sendMail = async (mailOptions) => {
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log("error: ", err);
} else {
console.log(`Mail sent succesfully!`);
}
});
}
所以简而言之,我的问题是 nodemailer 似乎在完成循环后同时启动所有邮件(我可以确认这一点,因为在我的控制台中,"Processing address ..." 的日志出现在来自nodemailer,所以我只想让这个过程绝对同步,有人可以帮我吗?:(
您的 sendMail 函数本质上不是异步的。它正在启动一个异步函数(即 transporter.sendMail
),然后立即 returning undefined
(因为没有 return 语句)。
exports.sendMail = function(mailOptions){
return new Promise(function (resolve, reject){
transporter.sendMail(mailOptions, (err, info) => {
if (err) {
console.log("error: ", err);
reject(err);
} else {
console.log(`Mail sent successfully!`);
resolve(info);
}
});
});
}
现在,当您 await mailer.sendMail(mailContent)
承诺将 returned 并且实际上会有一些等待。也就是承诺的决议或者拒绝。
确保有一个 try/catch 块包含所有 await 运算符。