如何通过nodemailer同步发送邮件?

Rod*_*Gra 3 javascript email synchronous node.js nodemailer

我正在使用带有nodemailer模块的nodejs 创建一个应用程序来发送邮件。

我的应用程序的过程是读取包含姓名和电子邮件的列表,使用jimp创建 png 文凭文件(基于每个姓名和电子邮件),然后通过 nodemailer 存储并发送每个文件到每个不同的邮件地址,所有这些完成后我想删除每个文件,但所有这些都以同步方式进行,因为 png 文凭和发送电子邮件需要一些时间:

我的列表的语法是:

const list = [
  [name1, email1@mail.com]
  [name2, email2@mail.com]
  [        ...           ]
  [namex, emailx@mail.com]
]
Run Code Online (Sandbox Code Playgroud)

实际上我想等待每封邮件发送完毕,因为 gmail 似乎在处理同时发送多封邮件时存在问题,发送 13 或 15 封邮件后,它会显示下一个错误:

error:  { Error: Data command failed: 421 4.7.0 Temporary System Problem.  Try again later (10). x12sm4645987otk.1 - gsmtp
Run Code Online (Sandbox Code Playgroud)

因此,为了实现这一目标,我使用经典的 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)
}
Run Code Online (Sandbox Code Playgroud)

这是我的 sendMail 函数:

exports.sendMail = async (mailOptions) => {
    transporter.sendMail(mailOptions, (err, info) => {
        if (err) {
            console.log("error: ", err);
        } else {
            console.log(`Mail sent succesfully!`);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

所以简而言之,我的问题是,nodemailer 似乎在完成循环后同时启动所有邮件(我可以确认这一点,因为在我的控制台中,“处理地址...”的日志出现在来自 nodemailer 的日志之前,所以我只是想让这个过程绝对同步,有人可以帮助我吗?:(

Fis*_*dNo 7

您的 sendMail 函数本质上不是异步的。它启动一个异步函数(即transporter.sendMail),然后立即返回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);
         }
      });
   });

}
Run Code Online (Sandbox Code Playgroud)

现在,当你的await mailer.sendMail(mailContent)承诺将被返回时,实际上会有一些东西等待。即对承诺的决议或拒绝。

确保有一个包含任何await 运算符的try/catch 块。