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

Abd*_*had 10 node.js promise async-await nodemailer

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

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

//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;
Run Code Online (Sandbox Code Playgroud)

这是我称之为的路线:

//imports including the mail_file.js

//somepath.js
router.post('/somepath',(req,res,next)=>{
      sendresetmail=async()=>
            {
                parameters={
                         //some email parameters
                }
                return await sendmail(params);

            }   
       sendmail()
       .then(response=>{
            //response is always false even when the mail is sent
             })
        .catch(err=>{
           //error
             })
  })
Run Code Online (Sandbox Code Playgroud)

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

Gan*_*wad 30

transporter.sendMail 不返回承诺,它使用回调函数。改变你的代码

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

}
Run Code Online (Sandbox Code Playgroud)

正如我之前所说,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);
    }
   });
   }
   })
Run Code Online (Sandbox Code Playgroud)

现在你可以在你的其他函数中使用这个wrappedSendMail函数,如下所示,

 sendmail= async(req)=>{      
  var mailOptions = {
      //mailoptions
  };
  let resp= await wrapedSendMail(mailOptions);
  // log or process resp;
   return resp;
} 
     
Run Code Online (Sandbox Code Playgroud)

  • 截至 2020 年 5 月,`nodemailer` v6.4.8 支持同步版本和异步版本的 `sendMail`。```sendMail(mailOptions: Mail.Options, callback: (err: Error | null, info: SentMessageInfo) => void ): 空白; sendMail(mailOptions: Mail.Options): Promise<SentMessageInfo>;``` (3认同)
  • 尽管库现在支持异步,并且“省略回调”现在是问题的答案,但这仍然是一个很好的答案。这个答案至少是我在谷歌上搜索“nodemailer sendMail with Promise”的第一个结果,所以我认为对于未来的寻求者来说,在原始答案顶部编辑 @newguy 的评论是有用的。 (2认同)

And*_*rew 21

根据Nodemailer 文档

所有公共 Nodemailer 方法都支持回调和承诺(如果省略回调)。如果你想在 Nodemailer 中使用 async..await,你至少需要有 Node v8.0.0

一个例子可以在这里找到:https : //nodemailer.com/about/#example