Javascript 即使发生异常,如何继续异步查找?

Javascript 即使发生异常,如何继续异步查找?,javascript,asynchronous,Javascript,Asynchronous,在我的Node.js应用程序中,我有一个名为employees的数组,用于存储电子邮件列表。我分析了这个列表,并尝试按包分别为每个人发送电子邮件。我也使用软件包 循环的某个迭代中可能会发生错误。即使发生错误,我也要继续循环。在我的情况下,似乎我不能使用continue语句,您推荐什么解决方案 const forAsync = require('for-async'); forAsync(employees, (employee) => { return new Promise(r

在我的
Node.js
应用程序中,我有一个名为
employees
的数组,用于存储电子邮件列表。我分析了这个列表,并尝试按包分别为每个人发送电子邮件。我也使用软件包

循环的某个迭代中可能会发生错误。即使发生错误,我也要继续循环。在我的情况下,似乎我不能使用
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);
            }
        }));
    });
});
router.post('/notifications',函数(请求、响应){
//向数据库发出sql请求。
Promise.all([firstQuery,secondQuery,thirdQuery])。然后(responses=>{
//一些逻辑

wait Promise.all(employees.map)(async(employees)=>{/由于您使用的是Node.js的最新版本,因此我将为此使用
async
函数,并将
用于
循环

首先,由于
transporter.sendmail
是一个旧的回调函数,我将在一些实用程序模块中为它创建一个包装器:

function sendEmail(transporter, options) {
    return new Promise((resolve, reject) => {
        transporter.sendMail(options, (error) => {
            if (error) {
                reject(error);
            } else {
                resolve();
            }
        });
    });
}
然后循环(在
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
可防止任何错误或拒绝承诺从循环中传播出去,因此循环将继续。请注意,电子邮件将以串行方式发送,而不是并行方式发送

我已经删除了1秒延迟,假设您并不真正需要它,但是如果您需要它,请在实用程序中添加一个
delay
函数:

function delay(ms, value) {
    return new Promise(resolve => setTimeout(resolve, ms, value));
}
然后将其插入
for
循环:

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


由于您使用的是Node.js的最新版本,因此我将使用
async
函数来实现此功能,并使用
来实现
循环

首先,由于
transporter.sendmail
是一个旧的回调函数,我将在一些实用程序模块中为它创建一个包装器:

function sendEmail(transporter, options) {
    return new Promise((resolve, reject) => {
        transporter.sendMail(options, (error) => {
            if (error) {
                reject(error);
            } else {
                resolve();
            }
        });
    });
}
然后循环(在
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
可防止任何错误或拒绝承诺从循环中传播出去,因此循环将继续。请注意,电子邮件将以串行方式发送,而不是并行方式发送

我已经删除了1秒延迟,假设您并不真正需要它,但是如果您需要它,请在实用程序中添加一个
delay
函数:

function delay(ms, value) {
    return new Promise(resolve => setTimeout(resolve, ms, value));
}
然后将其插入
for
循环:

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


什么是
forAsync
?为什么是一秒钟的延迟?基本上,如果您想要循环(这可能是在
forAsync
中实现的)若要继续,请确保在循环体中捕获错误/拒绝。但在我看来,您是这样做的,因为内部承诺可能会拒绝,但外部承诺会捕获该拒绝,并通过
将其转化为
未定义的
实现。最后,catch
我使用了该包。它可能已经过时了,b但是它工作没有问题。无论如何,我正在考虑用其他东西替换它。我将感谢您的建议。遗憾的是,该软件包文档没有告诉您它的用途。:-)无论如何,我想如果你使用的是Node.js的任何模糊的现代版本,我会使用一个
async
函数和一个
for
循环,里面有一个
wait
(如果你想一次做一件事)。:-)什么是
forAsync
(这可能是在
forAsync
中实现的)若要继续,请确保在循环体中捕获错误/拒绝。但在我看来,您是这样做的,因为内部承诺可能会拒绝,但外部承诺会捕获该拒绝,并通过
将其转化为
未定义的
实现。最后,catch
我使用了该包。它可能已经过时了,b但是它工作没有问题。无论如何,我正在考虑用其他东西替换它。我将感谢您的建议。遗憾的是,该软件包文档没有告诉您它的用途。:-)无论如何,我认为如果您使用的是Node.js的任何模糊的现代版本,我会使用一个
async
函数和一个
for
循环,其中包含一个
wait
(如果您想一次做一次这些事情的话):-)谢谢你的详细回答。我试图使用你帖子的最后一个选项。我不能在
承诺之前使用
等待
语句。所有的
。我看到这样的错误:
语法错误:等待只在异步函数中有效
。你有什么想法吗?你能再次检查我的帖子吗?我添加了我当前的代码。@Nurzhanogerbek-我会使用n
async
函数,这就是该示例和其他示例的目的。如果您不想使用
async
函数,请删除
wait
并使用履行和拒绝处理程序(
。然后
。catch
,…)。谢谢你的回答!谢谢你的详细回答。我试图使用你帖子的最后一个选项。我不能在
承诺之前使用
wait
语句。所有的
。我看到这样的错误:
SyntaxError:wait只在异步函数中有效。你有什么想法吗?你能再次检查我的帖子吗?我添加了我当前的代码@Nurzhanogerbek-我会使用
异步
函数,这就是该示例和其他示例的目的。如果您不想使用
异步
函数,请删除
等待
并使用履行和拒绝处理程序(
。然后
。捕获
,…)。谢谢您的回答!