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

Nodemailer email confirmation using Async/Await

我正在使用 nodemailer 发送邮件。我需要知道邮件是否已发送然后更新我的数据库但是邮件是在传输器中发送的(我认为 returns 承诺)这需要时间,因此 return 是始终为 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;

这是我称之为的路线:

//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函数的响应之后

Nodemailer v6.4.8同时支持同步版和异步版sendMail.sendMail(mailOptions: Mail.Options, callback: (err: Error | null, info: SentMessageInfo) => void): void ;发送邮件(邮件选项:Mail.Options):承诺;

这个答案仍然可以帮助需要了解如何承诺使用回调的函数的人。链接解释同一事物的文章 https://letsdqode.blogspot.com/2022/01/using-callbacks-with-async-await-or.html

原答案: transporter.sendMail 不是 return 承诺,它使用回调函数。更改您的代码

  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 there.But 你可以围绕它编写一个包装函数,这样你就可以在你的函数中使用 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 documentation:

All public Nodemailer methods support both callbacks and Promises (if callback is omitted). You need to have at least Node v8.0.0 if you want to use async..await with Nodemailer

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