【问题标题】:Sending multiple emails at once with nodemailer使用 nodemailer 一次发送多封电子邮件
【发布时间】:2020-10-18 11:34:04
【问题描述】:

我正在尝试使用nodemailer 根据数据库中的条目发送电子邮件。我几乎尝试了我能想到的任何事情(手动创建Promises 的数组并在Promise.all() 的调用中使用它,使用map 等),但我总是遇到同样的错误: UnhandledPromiseRejectionWarning: Error: Message failed: 450 SQLITE_ERROR: cannot start a transaction within a transactionnodemailer-documentation 明确指出 -- 当不传递回调-fn 时,transporter.sendMail()-function 被包装为一个承诺。但是,当我像这样手动定义这些承诺的数组时......

const transporter = nodemailer.createTransport(serverData);
const mailData = ...;

const arr = [transporter.sendMail(mailData), transporter.sendMail(mailData)];

...即使我没有使用Promise.all() '跑'过那个数组,同样的错误已经触发;数组中的函数只有在我手动指定时才会运行,这是一种误解吗?

无论如何,这是我完整的数据库代码;我正在使用sequelize 从数据库中检索数据。我已验证此任务的从数据库检索数据端没有问题。

class Mail extends Model {
...

  static resendUndeliveredMails(){
    this.findAll()
        .then((mails) => {
          return Promise.all(mails.map(async mail => {
             transporter.sendMail(mail.dataValues);
          }));
        })
        .catch((e) => {
          console.log(e);
        });
  }
}

任何帮助将不胜感激!提前谢谢你:)。

【问题讨论】:

    标签: javascript node.js sequelize.js nodemailer


    【解决方案1】:

    我已经用 promise.all 测试了 nodeMailer API,我没有发现任何问题这是我在下面使用的代码,你得到的另一件事是我认为与均衡器或 SQL 相关的错误导致你的错误SQLITE_ERROR UnhandledPromiseRejectionWarning: Error: Message failed: 450 SQLITE_ERROR: cannot start a transaction within a transaction 抛出了getting,而另一件事是您在promise 中编写异步的方式所有我认为是错误的我将在这里与您分享您应该编写函数的方式,但是关于你在运行promise之前关于promise触发的第一个问题。所有这些都是当你创建一个像这样[promise(arg)]这样的数组时你正在调用该函数,所以promise将启动并且即使你不这样做节点也会处理它把它放在promise.all里面

     static async resendUndeliveredMails() {
    try {
      const mails = await findAll();
      const mailerPromises = mails.map((mail) => transporter.sendMail(mail.dataValues));
      const responses = await Promise.all(mailerPromises);
      console.log(responses, "All Mails Have Been Sent Successfully");
    } catch (e) {
      console.log(e);
    }
    

    }

    const nodemailer = require("nodemailer");
    
    const transporter = nodemailer.createTransport({
      service: "gmail",
      auth: {
        user: "user",
        pass: "pass", // naturally, replace both with your real credentials or an application-specific password
      },
    });
    
    const mailOptions = {
      from: "user@gmail.com",
      to: "test@gmail.com",
      subject: "testing due",
      text: "Dudes, we really need your money.",
    };
    
    const mailOptions2 = {
      from: "user@gmail.com",
      to: "test1@gmail.com",
      subject: "LOL due",
      text: "Dudes, we really need your money.",
    };
    
    Promise.all([
      transporter.sendMail(mailOptions),
      transporter.sendMail(mailOptions2),
    ])
      .then((res) => console.log(res))
      .catch((err) => console.log(err));
    

    【讨论】:

    • 感谢您的回答!这澄清了我(仍然)在承诺方面做错了什么!我决定使用reduce-函数采取另一种方法,另见stackoverflow.com/a/21372567/10964093。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 2015-05-19
    相关资源
    最近更新 更多