节点js发送电子邮件与pdf同步附件

任务:从数据库获取查询=>生成多个pdf =>通过节点js发送邮件附件问题:这里的问题是在调用sendMail()函数生成pdf之前。 那么如何在所有pdf生成后才能调用sendMail函数?

pdfs = []; // Pdf generate code var generatePdf = function (rows) { return new Promise(function (resolve, reject) { for (var i = 0; i < rows.length; i++) { html = ejs.renderFile( 'views/voucher.ejs', { voucher: rows[i] }, function (error, success) { if (error) { console.log(error); } else { var pdf_path = '/srv/ voucher/uploads/voucher/' + Math.random().toString(36).substring(7) + '.pdf'; htmlToPdf.convertHTMLString(success, pdf_path, function (error, success) { if (error) { console.log('Oh noes! Errorz!'); console.log(error); } else { pdfs.push(pdf_path); console.log("Single"); console.log(pdfs); console.log('Woot! Success!'); } }); } }); } resolve(); }); } // send mail code var sendMail = function () { new Promise(function (resolve, reject) { console.log("All" + pdfs); pdfs.forEach(function (value, key) { // mail sending code }); }); }; var findVoucherAndSendMail = function () { return new Promise(function (resolve, reject) { var query = con.query('SELECT * FROM voucher limit 20', function selectAll(err, rows, fields) { if (err) { throw err; } resolve(rows); }); }); }; findVoucherAndSendMail().then(function (fromResolve) { return generatePdf(fromResolve); }).then(function () { return sendMail(); }).catch(function () { }); 

生成PDF时,您的问题链接到for循环中的asynchronous行为。 您的承诺在您的pdf生成之前已经解决。 您应该使用Promise.all来等待生成完成。

 function generatePdf(rows) { return Promise.all(rows.map(row => asyncPdfGeneration(row)); } function asyncPdfGeneration(row) { return new Promise(function (resolve, reject) { ...generate pdf resolve(pdf); } } 

第二个'then'在函数findVoucherAndSendMail()中,所以generateFdf()和sendMail()都会在findVoucherAndSendMail()完成后触发。

将第二个“then”放在generatePdf()

 findVoucherAndSendMail().then(function (fromResolve) { return generatePdf(fromResolve).then(function () { return sendMail(); }); }).catch(function () { }); 

编辑

你有没有尝试: resolve(pdfs); 而不是只是resolve();