Ну, некоторые люди могут приехать сюда и сказать вам использовать внешнюю систему очередей и бла-бла ... Но вы могли бы просто использовать простой старый Javascript, чтобы запланировать отправку 20 * 60 * 1000 миллисекунд в будущее, чтобы начать все , :)
Существует, однако, проблема с вашим кодом: вы ожидаете, что почтовая программа будет успешной, прежде чем отправлять ответ 200 - «Сообщение отправлено» пользователю. Назовите меня сумасшедшим, но я уверен, что пользователь не будет смотреть на окно браузера в течение 20 минут, так что вам, вероятно, придется ответить как можно скорее, а затем запланировать почту. Изменение вашего кода:
router.post('/', (req, res) => {
const DELAY = 20*60*1000 // min * secs * milliseconds
const transporter = nodemailer.createTransport(smtpTransport({
host: 'smtp.gmail.com',
port: 465,
auth: {
user: '[email protected]',
pass: 'pass123'
}
}));
const mailOptions = {
from: `"${req.body.name}" <${req.body.email}>`,
to: '[email protected]',
subject: 'Form send',
html: `Content`
};
res.status(200).json({ responseText: 'Message queued for delivery' });
setTimeout(function(){
transporter.sendMail(mailOptions, (error, info) => {
if (error)
console.log('Mail failed!! :(')
else
console.log('Mail sent to ' + mailOptions.to)
}),
DELAY
);
}
});
Существует множество возможных недостатков этого решения. Если вы ожидаете большой трафик на этой конечной точке, вы можете получить много запланированных обратных вызовов, которые будут потреблять стек. Кроме того, если что-то не удается, пользователь, конечно, не сможет это знать.
Если это большой/серьезный проект, подумайте об использовании этого пакета cronjob или использовании внешнего механизма хранения, где вы можете поставить в очередь эти «ожидающие» сообщения (Redis будет делать, и это невероятно просто) и выполнять разные задачи чтения процесса оттуда и выполнить отправку электронной почты.
РЕДАКТИРОВАТЬ: еще что-то увидели на вашем коде.
1) Вам, вероятно, не нужно создавать новый transport
внутри вашего обработчика POST, создавать его снаружи и повторно использовать.
2) В дополнение к указанным проблемам, если ваш сервер разбился, никакое электронное письмо никогда не будет отправлено.
3) Если вы все еще хотите сделать это в одном приложении Node.js, вместо того, чтобы планировать электронную почту по каждому запросу этой конечной точке, вам лучше хранить данные электронной почты (от, до, темы, тела) где-то и планировать каждые 20 минут функцию, которая будет получать все ожидающие сообщения электронной почты, отправлять их по одному, а затем перенести на повторный запуск через 20 минут. Это позволит вам снизить потребление памяти. Сбой сервера все еще потерял все электронные письма, но если вы добавите REDIS в микс, вы можете просто захватить все ожидающие сообщения от REDIS, когда начнется ваше приложение.
Возможно, слишком много для ответа, извините, если не было необходимости! :)
Эй, Лайош, ты тоже прочитал мой разум, я только что обновил свой ответ, чтобы включить те же проблемы :) – CharlieBrown
@CharlieBrown да, кажется, мы здесь похожи друг на друга :) –
Большое спасибо за указание на это вместе с @CharlieBrown! Я пойду за этим решением и отметю как мой принятый ответ. – ronnyrr