You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Nodemailer连接池批量发送个性化邮件的正确方式

批量发送专属邮件的正确实现及连接管理

核心问题分析

你当前的代码存在两个关键问题:

  • sendMail 使用回调异步执行,map 遍历完成时邮件可能还在发送中,无法准确判断所有邮件是否发送完毕
  • 开启了连接池(pool: true),若不手动关闭连接池,脚本会因连接保持而无法自动退出

正确实现步骤

  1. 改用Promise风格处理异步发送:Nodemailer的sendMail在不传入回调时会返回Promise,方便统一管理所有异步任务
  2. 收集所有发送任务的Promise:遍历数组生成每个邮件的发送Promise
  3. 等待所有任务完成后关闭连接池:用Promise.all等待全部发送任务结束,再调用transporter.close()关闭连接池,最后返回响应

修改后的完整代码

const nodemailer = require('nodemailer');
// 假设这是你的Express/axios路由处理函数
async function sendBulkEmails(req, res) {
  const arr = [
    {
      email: "something@something.com",
      content: "Hello user 1!"
    },
    {
      email: "something1@something.com",
      content: "Hello user 2!"
    }
  ];

  const transport = {
    // 你的邮件服务器认证信息
    pool: true,
    maxConnections: 20,
    maxMessages: Infinity
  };
  const transporter = nodemailer.createTransport(transport);

  try {
    // 生成所有邮件发送的Promise数组
    const mailPromises = arr.map(one => {
      const mailOptions = {
        from: "someone@mail.com",
        to: one.email,
        subject: "Test mail",
        text: one.content // 把专属内容加到邮件正文里
      };
      // 发送邮件并处理单个任务的结果
      return transporter.sendMail(mailOptions)
        .then(() => console.log(`Message sent to: ${one.email}`))
        .catch(err => {
          console.error(`Failed to send to ${one.email}:`, err);
          throw err; // 若需要让整体任务失败则抛出错误,否则可忽略继续
        });
    });

    // 等待所有邮件发送完成
    await Promise.all(mailPromises);
    console.log("All emails sent successfully");

    // 关闭连接池,释放资源
    await transporter.close();

    // 返回成功响应
    res.status(200).json({ message: "所有邮件已成功发送" });
  } catch (err) {
    console.error("邮件发送过程出错:", err);
    // 即使出错也要关闭连接池
    await transporter.close();
    // 返回错误响应
    res.status(500).json({ error: "部分邮件发送失败", details: err.message });
  }
}

关键细节说明

  • 连接池关闭时机:必须在所有邮件发送任务完成后(包括失败的情况)调用transporter.close(),否则会中断正在进行的邮件发送
  • 错误处理:Promise.all会在任何一个Promise失败时立即抛出错误,若希望即使部分邮件失败仍继续发送其他邮件,可以在单个Promise的catch中不抛出错误,而是收集错误信息最后统一返回
  • 邮件内容:不要忘记将content字段加入mailOptions的text或html属性,否则收件人看不到专属内容

内容的提问来源于stack exchange,提问作者Cookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:25:51