我有一个具有接收用户数据的功能,在该数据中,我有一个电子邮件数组,可以使用节点邮件程序在给定的电子邮件数组上发送电子邮件
现在,我正在尝试使用foreach循环来遍历数组,并且在每次迭代时,我都在使用回调函数来检查给定的电子邮件是否存在
(使用服务whoisxmlapi.com),该电子邮件将返回是否有效的电子邮件 然后,如果电子邮件有效,则通过nodemailer发送邮件,否则不是
回调工作正常,但是运行此foreach循环的功能在回调返回之前走得更远(我想等到所有电子邮件都已验证并发送后)
/* tried[1] async here */ function sendMails(fields) {
var transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: email_from,
pass: password
}
});
var mailOptions = {
from: email_from,
to: _send_to_.toString(),
subject: fields.email_subject,
text: fields.msg_type == 'text' ? fields.message_text : '',
html: fields.msg_type == 'html' ? fields.message_text : ''
};
let __vs_status__ = {
email: email,
email_v: false,
email_s: false
};
_send_to_ = fields.emails
_send_to_.forEach( /* tried[2] async here */ email => {
var verifyEmail = /* tried[2] await here */ verifyEmailExist(email, (ev) => {
console.log(ev.smtpCheck)
if (ev.smtpCheck == 'true') {
__vs_status__.email_v = true
transporter.sendMail(mailOptions, function (error, info) { //want to wait for this too but couldn't test bcz valid email wait was not working properly
if (error) {
console.log(error);
__vs_status__.email_s = false
} else {
__vs_status__.email_s = true
}
});
}
// console.log('pushing')
__email__info.push(__vs_status__)
// console.log(__email__info)
})
});
console.log(/* tried[1] await here */ __email__info) // this prints before loop and callbacks gets completed (don't want that)
}
// ----------------------------- EMAILS EXIST CHECK CALLBACK ---------------
function verifyEmailExist(email, callback) {
console.log('callback ' + email)
var email = email;
var api_key = apikey;
var api_url = 'https://emailverification.whoisxmlapi.com/api/v1?';
var url = api_url + 'apiKey=' + api_key + '&emailAddress=' + email;
https.get(url, function (response) {
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
callback(JSON.parse(str));
});
}).end();
}
我希望foreach循环在继续操作之前完成,并在for每个循环中验证电子邮件和发送状态
只是无法完成
我尝试了async / await,但是没有用(尝试过[reference] async / tryd [reference] await)
您只需安装所需的节点程序包,然后将一系列电子邮件传递给sendMails函数即可进行代码测试(并验证电子邮件,您需要使用api键)
答案 0 :(得分:2)
async / await在这里并不重要,因为它实际上将包装/解开承诺(您不能使用的承诺)
我真的没有在这里看到问题。您的console.log(__email__info)
和您的__email__info.push(__vs_status__)
都必须位于transporter.sendMail
的回调中
因此,以下内容:
_send_to_.forEach( /* tried[2] async here */ email => {
verifyEmailExist(email, (ev) => {
console.log(ev.smtpCheck)
if (ev.smtpCheck == 'true') {
__vs_status__.email_v = true
transporter.sendMail(mailOptions, function (error, info) { //want to wait for this too but couldn't test bcz valid email wait was not working properly
if (error) {
console.log(error);
__vs_status__.email_s = false
} else {
__vs_status__.email_s = true
}
__email__info.push(__vs_status__)
console.log(/* tried[1] await here */ __email__info)
});
}
})
});
答案 1 :(得分:0)
最好使用for循环,然后再使用每个循环,因为每个循环都包含回调。这里使用请求-承诺模块,因为它返回promise。 AND承诺util库的对象。这样可以将接受回调的方法转换为Promise。
const rp = require('request-promise'),
{promisify} = require('util');
function sendMails(fields) {
var transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
secure: false,
requireTLS: true,
auth: {
user: email_from,
pass: password
}
});
var mailOptions = {
from: email_from,
to: _send_to_.toString(),
subject: fields.email_subject,
text: fields.msg_type == 'text' ? fields.message_text : '',
html: fields.msg_type == 'html' ? fields.message_text : ''
};
let __vs_status__ = {
email: email,
email_v: false,
email_s: false
};
_send_to_ = fields.emails
for (var email of _send_to_) {
var ev = await verifyEmailExist(email)
console.log(ev.smtpCheck)
if (ev.smtpCheck == 'true') {
__vs_status__.email_v = true
const sendMail = promisify(transporter.sendMail).bind(transporter);
const info = await sendMail(mailOptions);
if (!info) {
console.log("error");
__vs_status__.email_s = false
} else {
__vs_status__.email_s = true
}
}
__email__info.push(__vs_status__)
}
console.log( /* tried[1] await here */ __email__info) // this prints before loop and callbacks gets completed (don't want that)
}
// ----------------------------- EMAILS EXIST CHECK CALLBACK ---------------
async function verifyEmailExist(email, callback) {
console.log('callback ' + email)
var email = email;
var api_key = apikey;
var api_url = 'https://emailverification.whoisxmlapi.com/api/v1?';
var url = api_url + 'apiKey=' + api_key + '&emailAddress=' + email;
const str = await rp(url);
return JSON.parse(str);
}