Как продолжить асин c выглядеть даже после исключения? - PullRequest
0 голосов
/ 24 апреля 2020

В моем приложении Node.js есть массив с именем employees, в котором хранится список электронных писем. Я анализирую этот список и пытаюсь отправить электронное письмо каждому человеку индивидуально с помощью пакета nodemailer . Также я использую for-asyn c package.

Ошибка может произойти в одной из итераций l oop. Я хочу продолжить l oop, даже если произойдет ошибка. Похоже, я не могу использовать continue заявление в моем случае Какие решения вы рекомендуете?

const forAsync = require('for-async');

forAsync(employees, (employee) => {
    return new Promise(resolve => {
        // Set options.
        const options = {
            from: process.env.EMAIL,
            to: employee,
            subject: "System notification",
            html: html
        };

        // Send mail with defined transport object.
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                transporter.sendMail(options, (error) => {
                    if(error) {
                        console.log(error);
                        reject(error);
                    } else {
                        resolve();
                    }
                });
            }, 1000);
        }).then(() => {
            resolve();
        }).catch(error => {
            console.log(error);
        );
    });
});

РЕДАКТИРОВАТЬ:

router.post('/notifications', function(request, response) {
    // Make sql requests to the database.

    Promise.all([firstQuery, secondQuery, thirdQuery]).then(responses => {
        // Some logic

        await Promise.all(employees.map(async (employee) => { // <- PROBLEM
            try {
                await sendEmail(transporter, options);
            } catch (error) {
                // Error sending this specific email, just report it and ignore
                console.log(error);
            }
        }));
    });
});

1 Ответ

1 голос
/ 24 апреля 2020

Поскольку вы используете довольно свежую версию Node.js, я бы использовал для этого функцию async и for l oop.

Сначала, начиная с transporter.sendEmail это старая функция в стиле обратного вызова, я бы создал для нее обертку в некоторых служебных модулях:

function sendEmail(transporter, options) {
    return new Promise((resolve, reject) => {
        transporter.sendMail(options, (error) => {
            if (error) {
                reject(error);
            } else {
                resolve();
            }
        });
    });
}

Тогда l oop (в функции async) будет:

for (const employee of employees) {
    try {
        await sendEmail(transporter, {
            from: process.env.EMAIL,
            to: employee,
            subject: "System notification",
            html: html
        });
    } catch (error) {
        // Error sending this specific email, just report it and ignore
        console.log(error);
    }
}

try / catch предотвращает распространение ошибок или обещаний отказа от l oop, поэтому l oop продолжается. Обратите внимание, что электронные письма будут отправляться в серии , а не в параллельно .

Я убрал одну секунду задержки, если предположить, что вам действительно не нужно это, но если вы хотите, добавьте функцию delay в свои утилиты:

function delay(ms, value) {
    return new Promise(resolve => setTimeout(resolve, ms, value));
}

Затем вставьте это в for l oop:

await delay(1000);

Если вы хотите сделать это параллельно, а не последовательно, вам понадобится Promise.all и обработчик отклонения для отдельных обещаний:

await Promise.all(employees.map(async (employee) => {
    try {
        await sendEmail(transporter, {
            from: process.env.EMAIL,
            to: employee,
            subject: "System notification",
            html: html
        });
    } catch (error) {
        // Error sending this specific email, just report it and ignore
        console.log(error);
    }
}));

или

await Promise.all(employees.map(employee => sendEmail(transporter, {
        from: process.env.EMAIL,
        to: employee,
        subject: "System notification",
        html: html
    }).catch(error) {
        // Error sending this specific email, just report it and ignore
        console.log(error);
    })
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...