使用Async/Await进行Nodemailer电子邮件确认

16

我正在使用nodemailer发送邮件。我需要知道邮件是否已发送,然后更新我的数据库,但是邮件被发送到传输器中(我认为传输器不返回承诺),这需要时间,因此即使邮件已发送,返回值始终为false。

这是我从其他路由调用的邮件发送文件。

// mail_file.js
// imports

sendmail = async (req) => {
  let transporter = nodemailer.createTransport({
    // settings
  });
  var mailOptions = {
    // mailoptions
  };
  let resp = false;
  await transporter.sendMail(mailOptions, function (error, info) {
    if (error) {
      console.log('error is ' + error);
      resp = false;
    } else {
      console.log('Email sent: ' + info.response);
      resp = true;
    }
  });
  return resp;
};

module.exports = sendmail;

当我记录邮件信息时,在somepath.js中的sendmail函数响应记录之后。

2个回答

45

Nodemailer v6.4.8支持同步版本和异步版本的sendMail。 sendMail(mailOptions:Mail.Options,callback: (err:Error | null,info:SentMessageInfo) => void):void; sendMail(mailOptions:Mail.Options):Promise; 这个回答可以帮助需要了解如何promisify使用回调函数的人。链接一篇解释相同内容的文章https://letsdqode.blogspot.com/2022/01/using-callbacks-with-async-await-or.html

  return new Promise((resolve,reject)=>{
 let transporter = nodemailer.createTransport({
    //settings
 });
var mailOptions = {
   //mailoptions
};
let resp=false;

transporter.sendMail(mailOptions, function(error, info){
    if (error) {
        console.log("error is "+error);
       resolve(false); // or use rejcet(false) but then you will have to handle errors
    } 
   else {
       console.log('Email sent: ' + info.response);
       resolve(true);
    }
   });
 })  

}

正如我之前所说,transport.sendMail() 函数使用回调函数,因此您无法在其中使用 await。但是,您可以编写一个包装函数,在需要更易读和干净的代码的函数中使用 await。只需考虑以下示例。

async function wrapedSendMail(mailOptions){
    return new Promise((resolve,reject)=>{
    let transporter = nodemailer.createTransport({//settings});

 transporter.sendMail(mailOptions, function(error, info){
    if (error) {
        console.log("error is "+error);
       resolve(false); // or use rejcet(false) but then you will have to handle errors
    } 
   else {
       console.log('Email sent: ' + info.response);
       resolve(true);
    }
   });
   }
   })
现在您可以像下面这样在其他函数中使用这个wrappedSendMail函数,
 sendmail= async(req)=>{      
  var mailOptions = {
      //mailoptions
  };
  let resp= await wrapedSendMail(mailOptions);
  // log or process resp;
   return resp;
} 
     

谢谢,它起作用了,但你能告诉我这里发生了什么,并且是否有其他方法来做到这一点,比如使用async/await或then/catch吗? - Abdul Ahad
8
截至2020年5月,nodemailer v6.4.8支持sendMail同步版本和异步版本。其中,同步版本需要回调函数作为参数(callback),而异步版本则返回一个Promise对象。具体用法可参考以下代码: sendMail(mailOptions: Mail.Options): Promise;``` - newguy
2
这是一个非常好的答案,即使现在该库支持异步操作,“省略回调”仍然是问题的答案。这个答案至少是我在谷歌搜索“使用promises发送nodemailer邮件”的第一个结果,所以我认为将@newguy的评论编辑到原始答案的顶部对于未来的搜索者会很有用。 - Asleepious

27

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接