如果在调用函数后运行语句

时间:2018-10-02 09:55:33

标签: node.js dialogflow nodemailer

我正在设置一个邮件程序,以将有关约会请求的一些详细信息发送给相关收件人。

我遇到了一个问题,即运行IF语句以决定谁应该是必要的收件人的过程在电子邮件传输器之后运行,并给我一个错误,指出尚未定义任何收件人。

这是代码

let recipientEmail;

if (careHome === 'ACareHome') {
    admin.database().ref('managers').once("value").then((snapshot) => {
        let managerEmail = snapshot.child("Manager Name").val();
        recipientEmail = managerEmail;
        console.log(`Recipient is ${recipientEmail}`);
   });
}

const mailOptions = {
    from: '*****', // sender address
    subject: `An appointment has been requested at ${ACareHome}.`,
    html: `Hello, an appointment has been booked at ${ACareHome} on ${date} at ${time}. The requestors name is, ${firstName}. You can email them on ${email}.` 
};

mailOptions.to = recipientEmail;

transporter.sendMail(mailOptions, function(error, info){
    if(error){
        return console.log(error);
    }
    console.log('Message sent: ' + info.response);
})

在Firebase日志中,出现这些错误

enter image description here

这表明IF语句在传输函数导致错误后运行。

我已经尝试了所有方法,但是似乎无法发挥作用!

感谢帮助,欢呼!

1 个答案:

答案 0 :(得分:3)

从数据库中提取数据是异步的,您当前的代码将忽略该数据,并尝试在诺言解决之前继续执行。

当人们不习惯承诺时,这是一个非常常见的错误。承诺基本上是漂亮的回调,而不是(err, info).then(还有其他几个)的函数。

您需要将电子邮件代码放入.catch函数中。这样它就会变成这样:

.then

我在这里做了三件事。

  1. 为方便起见,我将所有内容包装在一个函数中。
  2. 我已将发送电子邮件的代码移至promise function sendEmail() { let recipientEmail; if (careHome === 'ACareHome') { admin.database().ref('managers').once("value").then((snapshot) => { let managerEmail = snapshot.child("Manager Name").val(); recipientEmail = managerEmail; console.log(`Recipient is ${recipientEmail}`); const mailOptions = { from: '*****', // sender address subject: `An appointment has been requested at ${ACareHome}.`, html: `Hello, an appointment has been booked at ${ACareHome} on ${date} at ${time}. The requestors name is, ${firstName}. You can email them on ${email}.` }; mailOptions.to = recipientEmail; return new Promise(function promise(resolve, reject) { transporter.sendMail(mailOptions, function(error, info){ if (error) { return console.log(error); return reject(error); } console.log('Message sent: ' + info.response); return resolve(info); }); }); }); } } 函数中。这意味着一旦从数据库中获取了某些内容,您就在发送电子邮件,因此您现在正在等待响应。
  3. 我已经将transporter.sendMail包装在一个函数中。有一些实用程序可以执行此操作,但为清楚起见,我已向您展示了如何手动执行此操作。这意味着从点1开始的新函数现在返回一个Promise。现在,您可以通过调用.then来使用顶部函数sendMail,就像完成数据库代码一样。

通常不习惯通过将诸如Bluebird.promisify之类的任何面向回调的代码包装起来,或者以我自己的方式包装面向回调的函数,而不混合使用回调和承诺代码。这意味着您只需要处理sendMail().then(result...).catch(error...).then类型的代码。

如果您已经了解Promises vs Callbacks,我深表歉意,这只是我在问题上看到的一个常见主题,因此我已经完整回答了。