Как исправить «Функция вернула неопределенное, ожидаемое обещание или значение» - PullRequest
0 голосов
/ 14 июня 2019

То, что я пытаюсь выполнить с помощью функции Firebase:

  1. Чтение из адресов электронной почты базы данных Firebase для пакетной электронной почты.
  2. Прокрутка каждого из них и отправка электронных писем.

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

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const https = require('axios');

exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(() => {

    let emailsToSend = [];

    async function getTests (){
         admin.firestore()
         .collection("tests")
         .get()
         .then(querySnapshot => {
            querySnapshot.forEach(doc => {
                emailsToSend.push(doc.data())
            });
        })
        .catch(function (error) {
            console.error(error);
        });
    }

    async function send (address){
        let body = { 
             //MANDRILL INFO REMOVED
        };

        let endpoint = 'https://mandrillapp.com/api/1.0/messages/send-template.json';

        https.post(endpoint, body)
            .then((result) => {
                console.log('SUCCESS');
            })
            .catch(function (error) {
                console.error(error);
            });
    }

    async function init() {
        await getTests();

        for (const email of emailsToSend) {
            await send(email.address);
        }
    }

    init();

});

Ответы [ 3 ]

0 голосов
/ 14 июня 2019

Попробуйте:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const https = require('axios');

exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(() => {

    let emailsToSend = [];

    function getTests (){
         return new Promise((resolve, reject) => {
            admin.firestore()
            .collection("tests")
            .get()
            .then(querySnapshot => {
              querySnapshot.forEach(doc => {
                emailsToSend.push(doc.data())
              });
            resolve(emailsToSend);
          })
        .catch(function (error) {
            reject(error)
        });
       });
    }

    async function send (address){
        let body = { 
             //MANDRILL INFO REMOVED
        };

        let endpoint = 'https://mandrillapp.com/api/1.0/messages/send-template.json';

        https.post(endpoint, body)
            .then((result) => {
                console.log('SUCCESS');
            })
            .catch(function (error) {
                console.error(error);
            });
    }

    async function init() {
        const emailsToSend = await getTests();

        for (const email of emailsToSend) {
            await send(email.address);
        }
    }

    init();

});

Это может помочь вам.

0 голосов
/ 29 июня 2019

так что вы почти там. Проблема в том, что вы ничего не возвращаете. Вы должны исправить это, просто выполнив:

Обещание возврата

// code ...

exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(() => {
    // code

    return init();
}

Использовать асинхронно

// code ...

exports.sendEmail = functions.pubsub.topic('nightly_topic').onPublish(async () => {
    // code

    await init();
}

Примечание: асинхронная функция всегда возвращает Promise.

Предложение

В своем коде вы отправляете электронные письма по одному. await send(email.address); Эта строка кода ожидает отправки электронного письма, а затем отправляет следующее, что неэффективно.

Мое предложение - отправлять все электронные письма одновременно и возвращать обещание, которое разрешается при отправке каждого электронного письма. Это должно выглядеть примерно так:

//change this 
for (const email of emailsToSend) {
  await send(email.address);
}

// --------------into this--------------------------------

//This is an array of promises
const promises = emailsToSend.map(email => {
    return send(email.address);
});

await Promise.all(promises);

Надеюсь, это поможет:)

0 голосов
/ 14 июня 2019

Вам не хватает операторов return из ваших функций. return https.post(... и т. Д.

...