Наиболее простой формой здесь было бы просто обернуть функцию обратным вызовом (нодмалером) в Promise:
exports.createListing = (req, res) => {
// Validate request
if(!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
// Set options after the request was verified.
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
port: 465,
auth: {
user: 'YOUR_GMAIL_SERVER',
pass: 'YOUR_GMAIL_PASSWORD'
}
});
const listing = new Listing({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
listing.save()
.then(data => new Promise((resolve, reject) => {
var mailOptions = {
to: data.email,
subject: 'ENTER_YOUR_SUBJECT',
html: `<p>${data.title}</p>
<p>${data.city}</p>
<p>${data.street}</p>`,
...
};
smtpTransport.sendMail(mailOptions,
(error, response) => {
if (error) {
reject(error);
} else {
resolve(data);
}
});
})
.then(data => {
smtpTransport.close(); // this awaited the actual send
res.send(data);
}
.catch(err => {
res.status(500).send({
message: err.message || "Some error occurred while creating the listing."
});
});
};
Обратите внимание, что resolve(data)
здесь эффективно проходит через результат кследующая ссылка в цепочке обещаний, которая лучше, чем вложение цепочек обещаний в той же области, просто чтобы иметь доступ к одному и тому же значению. Тогда у вас также есть единственная точка для catch()
, когда один из методов не работает.
Тем не менее, было обращено внимание, что текущий API фактически вернет Promise
при вызове без обратного вызова, но затемвам, вероятно, понадобится синтаксис async
и await
, чтобы сделать доступ к вещам более чистым:
exports.createListing = async (req, res) => { // <-- mark block as async
// Validate request
if(!req.body.content) {
return res.status(400).send({
message: "Fields can not be empty"
});
}
// Set options after the request was verified.
const smtpTransport = nodemailer.createTransport({
service: 'Gmail',
port: 465,
auth: {
user: 'YOUR_GMAIL_SERVER',
pass: 'YOUR_GMAIL_PASSWORD'
}
});
const listing = new Listing({
title: req.body.title,
city: req.body.city,
street: req.body.street,
businessname: req.body.businessname,
description: req.body.description
});
try { // try..catch for error handling
let data = await listing.save(); // await the save
var mailOptions = {
to: data.email,
subject: 'ENTER_YOUR_SUBJECT',
html: `<p>${data.title}</p>
<p>${data.city}</p>
<p>${data.street}</p>`,
...
};
await smtpTransport.sendMail(mailOptions); // await the sendMail
smtpTransport.close(); // this awaited the actual send
res.send(data);
} catch(err) {
res.status(500).send({
essage: err.message || "Some error occurred while creating the listing."
}
};
Также важно отметить, что этот подход serial в исполнении. Так что здесь письмо не отправляется, если данные не сохранены правильно. Это может или не может быть вашим предполагаемым случаем, но простое создание Обещания должно как минимум соответствовать правильному направлению.