Если оператор выполняется после вызываемой функции - PullRequest
0 голосов
/ 02 октября 2018

Я настраиваю почтовую программу на отправку электронного письма соответствующему получателю о некоторых деталях запроса на встречу.

У меня возникла проблема, из-за которой выполняется оператор 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 голосов
/ 02 октября 2018

Извлечение данных из вашей базы данных является асинхронным, ваш текущий код игнорирует это и пытается продолжить до разрешения обещания.

Это довольно распространенная ошибка, когда люди не привыкли к обещаниям.Обещания - это в основном симпатичные обратные вызовы, вместо (err, info) вы получаете функцию .then и .catch (и несколько других).

Вам необходимо поместить свой код электронной почты в функцию .then.Так что это будет примерно так:

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

Я сделал три вещи здесь.

  1. Я все обернул в функцию для простоты.
  2. Я переместил код отправки электронного письма в функцию обещания .then.Это означает, что как только что-то будет получено из базы данных, которую вы отправляете по электронной почте, теперь вы ждете ответа.
  3. Я заключил в функцию transporter.sendMail.Для этого есть утилиты, но для ясности я показал вам, как это сделать вручную.Это означает, что новая функция из пункта 1 теперь возвращает обещание.Теперь вы можете использовать верхнюю функцию sendMail так же, как вы делали код вашей базы данных, вызывая sendMail().then(result...).catch(error...).

Часто более идиоматично не смешивать код обратного вызова и обещания путем обертываниялюбой код, ориентированный на обратный вызов, с такими вещами, как Bluebird.promisify, или завершение функции, ориентированной на обратный вызов, вручную, как я.Это означает, что вы просто имеете дело с кодом типа .then и .catch.

Прошу прощения, если вы уже знали о Promises vs Callbacks, это обычная тема, которую я вижу по вопросам, поэтому я ответил на неев полном объеме.

...