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

Posted

技术标签:

【中文标题】使用 Async/Await 的 Nodemailer 电子邮件确认【英文标题】:Nodemailer email confirmation using Async/Await 【发布时间】:2019-10-23 18:48:59 【问题描述】:

我正在使用 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;

这就是我所说的路线:

//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
             )
  )

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

【问题讨论】:

【参考方案1】:

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


正如我之前所说,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;
 
     

也许,nodemailer 现在支持异步等待,但这个答案仍然可以帮助需要了解如何承诺使用回调的函数的人。链接解释相同内容的文章 https://letsdqode.blogspot.com/2022/01/using-callbacks-with-async-await-or.html

【讨论】:

谢谢,它成功了,但你能告诉我这里发生了什么吗?是否有其他方法可以做到这一点,比如使用 async/await 或 then/catch? 截至2020年5月nodemailerv6.4.8同时支持sendMail.sendMail(mailOptions: Mail.Options, callback: (err: Error | null, info: SentMessageInfo) => void): void; sendMail(mailOptions: Mail.Options): Promise<SentMessageInfo>;的同步版本和异步版本 这曾经是并且现在仍然是一个很好的答案,尽管该库现在支持异步,并且“省略回调”现在是问题的答案。这个答案至少是我在谷歌上搜索“nodemailer sendMail with promises”的第一个结果,所以我认为在原始答案顶部编辑 @newguy 的评论对未来的求职者很有用。【参考方案2】:

根据Nodemailer documentation:

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

可以在此处找到示例:https://nodemailer.com/about/#example

【讨论】:

以上是关于使用 Async/Await 的 Nodemailer 电子邮件确认的主要内容,如果未能解决你的问题,请参考以下文章

async与await的使用

Webdriverio 使用 async/await - 推荐啥? [关闭]

.NET Web应用中为什么要使用async/await异步编程

async和await

async和await

async和await