如何等待生成 pdf Javascript

How to wait until a pdf is generated Javascript

我正在使用节点 html-pdf 生成 pdf 并使用 nodemailer 使用 node-cron 每分钟自动发送一封包含 pdf 的电子邮件,如以下代码所示:

cron.schedule('* * * * *', () => {
    
    // function to generate scan report using html-pdf
    report.getScanReport();

    // e-mail message options
    let mailOptions = {
        from: {{some_email}},
        to: {{some_email}},
        subject: 'Testing',
        text: 'See PDF attachment',
        attachments: [{
            filename:'test.pdf',
            path: 'C:/Users/test.pdf',
            contentType: 'application/pdf'
        }]
    };

    // Send e-mail
    transporter.sendMail(mailOptions, function(error, info) {
        if (error) {
            console.log(error);
        } else {
            console.log('Email sent: ' + info.response);
        }
    });
})

问题是生成 pdf 大约需要 10 秒左右,因此程序会尝试在生成的 pdf 文件存在之前发送电子邮件,然后我收到错误消息:Error: ENOENT: no such file or directory

getScanReport() 函数的工作原理供参考:

const getScanReport = () => {
      Promise.all([
        pool.query(query1),
        pool.query(query2)
    ]).then(function([results1, results,]) {
        var obj1 = results1.rows;
        var obj2 = results2.rows;

        ejs.renderFile('./views/pages/scanreport.ejs', {scanObj: scanObj, woObj: woObj}, (err, data) => {
        if (err) {
            console.log(err);
        } else {
            let options = {
            "height": "11.25in",
            "width": "8.5in",
            "header": {
                "height": "20mm"
            },
            "footer": {
                "height": "20mm",
            },
            };
            let filename = "test.pdf";
            pdf.create(data).toFile(filename, function (err, data) {
            let fileloc = 'C:/Users/' + filename;
            if (err) {
                console.log(err);
            } else {
                console.log("Successfully created pdf");
            }
            })
        }
        });
    });
} 

有没有办法确保在尝试发送电子邮件之前已生成 pdf?

假设您正在使用这个 NPM 包:https://www.npmjs.com/package/html-pdf-node, 您可以使用它提供的承诺在创建 PDF 文件后执行某些操作。

您可以看到它创建了一个 PDF,然后然后 执行了额外的代码。我对其进行了一些编辑以使其更易于理解。

html_to_pdf.generatePdf(file, options).then(() => {
  // this code will execute after the PDF has been generated.
});

如果您使用的是不同的包,请问link。谢谢。

假设您可以修改 getScanReport 函数,使用 Promise. Then in your email function, use async / await 等待该承诺。

(如果您不经常使用 promises 和 async / await,您可以单击链接阅读更多有关它们如何工作的信息。)

例如(编辑自 post 现在包括 getScanReport 内部工作):

report.getScanReport = () => new Promise( 

    //announcePDFReady() is a function we call to resolve our promise

    announcePDFReady => {

        Promise.
            all( [ /* ... */ ] ).
            then( function( [ results1, results2 ] ) {

                /* ... */

                renderFile( /* ... */ ( err, data ) => {

                    /* ... */

                    pdf.create( data ).toFile( filename, ( err, data ) => {
                        
                        let fileloc = 'C:/Users/' + filename;
                        if (err) {
                            console.log(err);
                        } else {
                            console.log("Successfully created pdf");
                            //announce ready right here!
                            announcePDFReady( data );
                        }

                    } )

                } )

            } )
            
    }

);


//...
//we write 'async' before the cron job function definition
async () => {
    //this is inside the cron job function

    const pdfIsReady = await report.getScanReport();
    //since report.getScanReport() returns a promise,
    //'await' here means our code will stop until the promise resolves.


    if( pdfIsReady === false ) {
        //it failed. Do something? Ignore it?
    } else {

        //pdf is ready. We can send the email
    
        //etc.

    }
}