创建 pdf 时节点中的同步 mysql 查询

synchronous mysql queries in node when creating a pdf

嗨,我正在尝试使用 MySQL 数据库中的数据编写 PDF 文件,但是当我 运行 脚本时,它告诉我我结束了 PDF 文件的创建,然后我尝试向其中插入数据......我认为这是因为节点中的 MySQL 是 Asynchronous 。有什么解决办法吗? 这是我的代码...

var project_ID = 1;
var PDFDocument = require('pdfkit');
$('#pdf').click(function(e) {
    e.preventDefault();
    var pdf = new PDFDocument;
    pdf.pipe(fs.createWriteStream(__dirname + '/../MyFile.pdf'));
    var option;
    switch ($("input[name=report-type]:checked").val()) {
        case 'all-issues':
            option = {project_id: project_ID};
            break;

        case  'all-issues-customer':
            option = {project_id: project_ID, customer: customer};
            break;
    }
    connection.getConnection(function (err, conn) { //make connection to DB
        if (err) { //error handling
            showNotification('error connecting: ' + err.stack, 'danger', 'glyphicon glyphicon-tasks');
            return;
        }
        conn.query('SELECT issues.id, issues.dbid , issues.date, issues.charm , issues.defect ,issues.key , issues.status, issues.summary, issues.description , actions.date as action_date, actions.description as action_desc FROM issues' +
            ' INNER JOIN actions on issues.id = actions.issue_id WHERE ? ', [option], function (error, data) {
            if (error) {
                showNotification('Error :' + error, 'danger', 'glyphicon glyphicon-tasks');
            } else {
                var lastID = -1;
                data.forEach(function (data) {
                    if (lastID !== data.id) {
                        lastID = data.id;
                        pdf.addPage();
                        pdf.text('Number :' + data.dbid).moveDown();
                        pdf.text('Customers :            ');
                        pdf.text('Baseline :            ');
                        pdf.text('Error/Wish :            ' + data.key).moveDown();
                        pdf.text('Charm :  ' + data.charm + ' / Defect :  ' + data.defect + '                   Status : ' + data.status);
                        pdf.text('Summary :                ' + data.summary);
                        pdf.text('Description :            ' + data.description).moveDown();
                        pdf.text('Actions/ History :').moveDown();
                    }
                    pdf.text('          - date        : ' + convertDate(data.date));
                    pdf.text('            description : ' + data.description).moveDown();
                })
            }
        });
        conn.release();
    });
    pdf.end();
});

这是因为 Node.js 的异步性质。不过,您可以在几个区域快速更改代码以修复它。您有一些像 conn.release()pdf.end() 这样的调用 在您的回调 之外。

在下面的代码中,我将 conn.release()pdf.end() 移到了 mysql 连接回调的最后几行。

var project_ID = 1;
var PDFDocument = require('pdfkit');
$('#pdf').click(function(e) {
    e.preventDefault();
    var pdf = new PDFDocument;
    pdf.pipe(fs.createWriteStream(__dirname + '/../MyFile.pdf'));
    var option;
    switch ($("input[name=report-type]:checked").val()) {
        case 'all-issues':
            option = {project_id: project_ID};
            break;

        case  'all-issues-customer':
            option = {project_id: project_ID, customer: customer};
            break;
    }
    connection.getConnection(function (err, conn) { //make connection to DB
        if (err) { //error handling
            showNotification('error connecting: ' + err.stack, 'danger', 'glyphicon glyphicon-tasks');
            return;
        }
        conn.query('SELECT issues.id, issues.dbid , issues.date, issues.charm , issues.defect ,issues.key , issues.status, issues.summary, issues.description , actions.date as action_date, actions.description as action_desc FROM issues' +
            ' INNER JOIN actions on issues.id = actions.issue_id WHERE ? ', [option], function (error, data) {
            if (error) {
                showNotification('Error :' + error, 'danger', 'glyphicon glyphicon-tasks');
            } else {
                var lastID = -1;
                data.forEach(function (data) {
                    if (lastID !== data.id) {
                        lastID = data.id;
                        pdf.addPage();
                        pdf.text('Number :' + data.dbid).moveDown();
                        pdf.text('Customers :            ');
                        pdf.text('Baseline :            ');
                        pdf.text('Error/Wish :            ' + data.key).moveDown();
                        pdf.text('Charm :  ' + data.charm + ' / Defect :  ' + data.defect + '                   Status : ' + data.status);
                        pdf.text('Summary :                ' + data.summary);
                        pdf.text('Description :            ' + data.description).moveDown();
                        pdf.text('Actions/ History :').moveDown();
                    }
                    pdf.text('          - date        : ' + convertDate(data.date));
                    pdf.text('            description : ' + data.description).moveDown();
                })
            }
            conn.release();
            pdf.end();
        });
    });
});

这应该确保在回调逻辑完成之前不会进行这些调用。 注意 如果您在该回调中有一个(或更多)回调,您通常必须确保在这些回调中调用这些函数。你会发现自己经常处于 Callback Hell 的中间。

祝你好运!