在我的Node.js
应用程序中,我有一个名为employees
的数组,用于存储电子邮件列表。我解析了该列表,并尝试通过nodemailer软件包分别为每个人发送电子邮件。我也使用for-async包。
循环的一个迭代中可能发生错误。即使发生错误,我也想继续循环。看来我无法使用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);
}
}));
});
});
答案 0 :(得分:2)
由于您使用的是Node.js的较新版本,因此我将使用async
函数和一个for
循环。
首先,由于transporter.sendEmail
是旧的回调样式函数,因此我将在一些实用程序模块中为其创建包装器:
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
防止任何错误或承诺拒绝传播到循环之外,因此循环继续进行。请注意,电子邮件将以系列发送,而不是以 parallel 发送。
假设您确实不需要一秒钟的延迟,那么我已经将其删除了,但是如果需要,可以在您的实用程序中添加一个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);
}
}));
或
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);
})
);