首页 > 解决方案 > 使用 setTimeout 发送邮件

问题描述

我想每 200 毫秒发送一次电子邮件,但它似乎不适用于承诺:

我的功能:

SendMail.send = function(from, to, subject, body, name, logo) {
  var transporter, html,
      contactparam = _.find(options.blocks, { name: 'contactparam' }).params,
      smtpUsername = _.find(contactparam, { name: 'smtp_username' }),
      smtpPassword = _.find(contactparam, { name: 'smtp_password' }),
      smtpHost = _.find(contactparam, { name: 'smtp_host' }),
      smtpPort = _.find(contactparam, { name: 'smtp_port' }),
      compagny = _.find(contactparam, { name: 'compagny' }),
      firstname = _.find(contactparam, { name: 'firstname' }),
      facebookUrl = _.find(_.find(options.blocks, { name: 'socialparam' }).params, { name: 'facebook' }).value,
      twitterUrl = _.find(_.find(options.blocks, { name: 'socialparam' }).params, { name: 'twitter' }).value,
      linkedinUrl = _.find(_.find(options.blocks, { name: 'socialparam' }).params, { name: 'linkedin' }).value,
      secondaryColor = _.find(_.find(options.blocks, { name: 'themeparam' }).params, { name: 'secondary_color' }).value,
      loadedLogo = logo || _.find(_.find(options.blocks, { name: 'logoparam' }).params, { name: 'logo' }).value,
      websiteUrl = _.find(_.find(options.blocks, { name: 'mainparam' }).params, { name: 'url' }).value,
      templateFile = fs.readFileSync('./app/views/0-templates/' + options.template + '/mail.ejs', 'utf-8'),
      loadedName = name || (compagny && compagny.value) || (firstname && name && firstname.value + ' ' + name.value),
      ejsTemplate = ejs.compile(templateFile);

  html = ejsTemplate({
    logo: loadedLogo || '/images/LOGO.png',
    websiteUrl: websiteUrl,
    body: body,
    title: subject,
    facebookUrl: facebookUrl,
    twitterUrl: twitterUrl,
    linkedinUrl: linkedinUrl,
    secondaryColor: secondaryColor || '#1c1c1c'
  });

  if ((smtpUsername && smtpUsername.value !== '') && (smtpPassword && smtpPassword.value !== '') && (smtpHost && smtpHost.value !== '') && (smtpPort && smtpPort.value !== '')) {
    transporter = nodemailer.createTransport({
      host: smtpHost.value,
      pool: true,
      port: parseInt(smtpPort.value, 10),
      auth: {
        user: smtpUsername.value,
        pass: smtpPassword.value
      }
    });
  } else {
    transporter = nodemailer.createTransport({
      sendmail: true,
      newline: 'unix',
      path: '/usr/sbin/sendmail'
    });
  }

  return transporter.sendMail({
    from: loadedName + ' <' + from + '>',
    replyTo: from,
    to: to,
    subject: subject,
    html: html
  });
};

SendMail.arraySend = function(array) {
  var promises = [];
  promises = array.map(function (emailObj, index) {
    return new Promise(function () {
      setTimeout(function () {
        return sendMailHelper.send(emailObj.from, emailObj.to, emailObj.title, emailObj.htmlMessage);
      }, 200 * index);
    });
  });
  return promises;
};

使用我的功能:

Promise.all(sendMailHelper.arraySend(emailsArray)).then( function() {
  request.flash('success', 'Emails sent !');
  response.redirect('/');
});

电子邮件数组:

emailsArray.push({
  from: from,
  to: registration.cfc_user.email,
  title: 'Finale : ' + newTournament.name,
  htmlMessage: htmlMessage
});

问题:未发送电子邮件。

标签: node.jspromisesettimeoutnodemailer

解决方案


您不能return从超时调用的函数中调用。此外,调用这么多 Promise 似乎不是一个好主意。

最好的方法是将所有电子邮件分组到一个 Promise 中,返回一个已发送的电子邮件对象和带有错误的电子邮件:

SendMail.arraySend = array => {
    return new Promise(resolve => {
        let sent = [];
        let errors = [];

        const finalise = () => {
            if ((sent.length + errors.length) >= array.length) {
                resolve({ sent, errors });
            }
        };

        array.forEach((emailObj, index) => {
            setTimeout(function () {
                sendMailHelper.send(emailObj.from, emailObj.to, emailObj.title, emailObj.htmlMessage)
                .then(() => {
                    sent.push(emailObj);
                    finalise();
                });
                .catch(() => {
                    errors.push(emailObj);
                    finalise();
                })
            }, 200 * index);
        });
    });
};

推荐阅读