AWS Lambda и Promises: обратные вызовы не называются - PullRequest
1 голос
/ 11 мая 2019

Я предполагаю, что мне не хватает некоторых оснований для обещаний.У меня есть процесс, который находится в AWS Lambda, который загружает три файла, а затем производит вывод, который отправляется по электронной почте.

module.exports.test = async (event) => {
   var p = download1();
   var c = download2();
   var h = download3();

   await Promise.all([p, c, h]).then(() => {
     ... bunch of logic manipulating the data
     customers.forEach(i => {
       buildFile().then(data => {
         sendEmail(data).then(response => {
            console.log('Email sent successfully');
         });
       });
     });
   }, errHandler);
};

Функции buildFile и sendEmail возвращают Promise, но я никогда не получаю сообщение «Электронная почта отправлена ​​успешно».Он запускает код, но на самом деле никогда не возвращается до завершения Lambda (по крайней мере, я так думаю).

Насколько я понимаю, Promise будет выполнять обратный вызов, но теперь я думаю, что мне нужно сделать что-то похожее на то, как я делал загрузки в оригинальном Promise.all ().Это правильное направление?

Процесс должен получить файлы, затем он проходит через клиентов для создания каждого файла и отправки через SES.

Ответы [ 2 ]

6 голосов
/ 11 мая 2019

Вы ищете

module.exports.test = async (event) => {
  var p = download1();
  var c = download2();
  var h = download3();

  try {
    await Promise.all([p, c, h]);

    // ... bunch of logic manipulating the data
    var promises = customers.map(async (i) => {
      var data = await buildFile();
      var response = await sendEmail(data);
      console.log('Email sent successfully');
    });
    await Promise.all(promises);
  } catch(e) {
    errHandler(e);
  }
};

Ваша функция test не ожидала обещаний, которые вы создали в цикле forEach, поэтому лямбда-функция завершается до того, как все будет сделано.

1 голос
/ 11 мая 2019

@ Берги ответ правильный, однако я бы хотел немного его расширить и дать вам некоторые ресурсы, чтобы увеличить или укрепить свои Promises знания. Я буду использовать следующий фрагмент кода, он немного громоздкий, потому что я написал его на Google Chrome фрагментах, поэтому не стесняйтесь вставлять его туда и поиграть с ним:

(function() {
    const promise1 = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('Replicant');
        }, 300);
    });

    const promise2 = new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('Human?');
        }, 300);
    });

    function buildFile(type) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(`${type}`);
            }, 300);
        });
    }

    function sendMail(customer, answer) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(`Sent test to: ${customer}, he/she is a ${answer}`);
            }, 300);
        });
    }

    let customers = ['Rob Batty', 'Rachel', 'Deckard'];

    async function myFunc() {

        const [a, b, c] = await Promise.all([promise1, promise1, promise2]);
        const answers = [a, b, c];

//         const promises = customers.map(async (name, index) => {
//             const file = await buildFile(answers[index]);
//             const mail = await sendMail(name, file);
//             console.log(mail);
//         });

        const promises = customers.map((name, index) => {
            buildFile(answers[index])
                .then(file => sendMail(name, file))
                .then(sent => console.log(sent))
                // If you're going to use Promises this is important! :D
                .catch(err => console.log(err))
        });

        const [m1, m2, m3] = await Promise.all(promises);

        console.log(m1, m2, m3);
    }

    myFunc();
})()

Как указано в ответе, проблема связана с использованием forEach, почему? Ну, просто потому, что вы выполняете код asynchronous для метода типа synchronous, вы не очень хорошо ладите :), поэтому решение состоит в том, чтобы создать Array из Promises, как Factory. После функции map Promises равны Pending или Fullfiled или Rejected. Когда вы вызываете метод Promise.all(), вы ожидаете его результатов, и они дают вам значения или в вашем случае использования генерируют файл, а затем отправить электронное письмо пользователю. Я надеюсь, что это поможет вам лучше понять, как работает Promises. В конце я оставлю две очень важные ссылки, по крайней мере для меня, которые помогли мне в какой-то момент с Promises. Ура, Зигфрид.

...