简体   繁体   English

使用 nodemailer 一次发送多封电子邮件

[英]Sending multiple emails at once with nodemailer

I am trying to send an email based on the entries inside a database using nodemailer .我正在尝试使用nodemailer根据数据库中的条目发送电子邮件。 I have tried practically anything I can think of (manually creating an array of Promises and using that in a call of Promise.all() , doing that using a map , etc.), but I always keep getting the same error: UnhandledPromiseRejectionWarning: Error: Message failed: 450 SQLITE_ERROR: cannot start a transaction within a transaction .我几乎尝试了我能想到的任何事情(手动创建一个Promises数组并在Promise.all()调用中使用它,使用map等等),但我总是遇到同样的错误: UnhandledPromiseRejectionWarning: Error: Message failed: 450 SQLITE_ERROR: cannot start a transaction within a transaction The nodemailer -documentation clearly states that -- when not passing a callback-fn, the transporter.sendMail() -function is wrapped as a promise. nodemailer文档清楚地指出——当不传递回调 fn 时, transporter.sendMail()函数被包装为承诺。 However, when I am manually defining an array of those promises like so...但是,当我手动定义一个像这样的承诺数组时......

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

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

... the same error already fires even though I have not even 'ran' through that array using Promise.all() ; ...即使我还没有使用Promise.all() '跑'过那个数组,同样的错误已经触发; is it a misconception that the functions in the array will only run when I manually specify?数组中的函数只会在我手动指定时运行,这是一种误解吗?

Anyhow, this is my complete code for the database;无论如何,这是我的数据库完整代码; I am using sequelize to retrieve the data from the database.我正在使用sequelize从数据库中检索数据。 I have verified that there are no problems on the retrieving-data-from-the-db-side of this task.我已验证此任务的从数据库端检索数据没有问题。

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);
        });
  }
}

Any help would be greatly appreciated!任何帮助将不胜感激! Thank you in advance :).先感谢您 :)。

I have tested nodeMailer API with promise.all and I did not found any problem with it this is the code I used below, and another thing the error you are getting is I think related to equalizer or SQL cause the error you are getting is being thrown by SQLITE_ERROR UnhandledPromiseRejectionWarning: Error: Message failed: 450 SQLITE_ERROR: cannot start a transaction within a transaction , and another thing the way you are writing async inside the promise all I think is wrong I will share with you here the way you should write the function, but about your fist question about the promises firing before you run promise.all that's all when you create an Array-like this [promise(arg)] you are calling the function at that moment so the promise will start and node will handle it even if you don't put it inside of promise.all我已经用 promise.all 测试了 nodeMailer API,我没有发现任何问题,这是我在下面使用的代码,而你得到的另一件事是我认为与均衡器或 SQL 相关,导致你得到的错误是由SQLITE_ERROR抛出UnhandledPromiseRejectionWarning: Error: Message failed: 450 SQLITE_ERROR: cannot start a transaction within a transaction ,以及你在 promise 内写异步的方式我认为是错误的我会在这里与你分享你应该写的方式功能,但你方关于你运行promise.all这一切之前的承诺射击拳头的问题,当你创建一个Array,像这样[promise(arg)]您所呼叫的那一刻的功能,因此承诺将启动,节点将处理即使你不把它放在 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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM