如何在node.js中下次执行之前等待数据

时间:2019-04-30 02:39:02

标签: node.js express server

如何在node.js中运行下一次执行之前等待数据。例如,我有3个部分需要执行。从作业表收集数据,从车辆表收集数据,然后运行我的jar文件。因此,控制台的当前输出为0->1->3->5->7->2->4->6。如何使其像0->1->3->2->4->5->6->7那样。我想等待第一个查询和第二个查询的数据,然后运行jar文件。

var express = require('express');
var router = express.Router();

router.post('/', function(req, res, next) {
    //console.log("pending data");

    console.log("0");

    var date = req.param('date');
    var joblist;
    var vehiclelist;

    console.log("1");

    res.locals.connection.query('SELECT * FROM job WHERE date = ?',[date] , function (error, results, fields) {
        console.log("2");
        if (error) throw error;
        joblist = JSON.stringify(results);
    });

    console.log("3");

    res.locals.connection.query('SELECT * FROM vehicle ' , function (error, results, fields) {
        console.log("4");
        if (error) throw error;
        vehiclelist = JSON.stringify(results);
    });

    console.log("5");

    var exec = require('child_process').exec, child;
child = exec('java -jar /home/java/testinput.jar',
  function (error, stdout, stderr){
    //console.log('stdout: ' + JSON.stringify(stdout));
    //console.log('stderr: ' + stderr);
    console.log("6");
    res.send(joblist+"  "+stderr);
    if(error !== null){
      console.log('exec error: ' + error);
    }
});
console.log("7");

});

module.exports = router;

1 个答案:

答案 0 :(得分:2)

问题在于以下内容:

function (error, results, fields) {
    console.log("2");
    if (error) throw error;
    joblist = JSON.stringify(results);
}

callback函数。您将在您的query()调用中传递该函数,并告诉它在完成查询后执行该函数。一旦您的代码请求该查询(不执行查询),它就会立即继续执行下一个代码。

在早期,解决方案是在回调函数中定义所有以后的动作 ,大致如下:

var express = require('express');
var router = express.Router();

router.post('/', function(req, res, next) {
    //console.log("pending data");

    console.log("0");

    var date = req.param('date');
    var joblist;
    var vehiclelist;

    console.log("1");

    res.locals.connection.query('SELECT * FROM job WHERE date = ?',[date] , function (error, results, fields) {
        console.log("2");
        if (error) throw error;
        joblist = JSON.stringify(results);

        console.log("3");

        res.locals.connection.query('SELECT * FROM vehicle ' , function (error, results, fields) {
            console.log("4");
            if (error) throw error;
            vehiclelist = JSON.stringify(results);

            console.log("5");

            // etc

            res.send('blah')
        });

    });

});

module.exports = router;

现代JS现在具有promise和async / await,它们通常被认为是异步代码https://javascript.info/async-await

中回调的更好替代品

根据后续评论的快速摘要:(这不是完全有效的代码,只是概念的示例)

var express = require('express');
var router = express.Router();

router.post('/', async function(req, res, next) {
    //console.log("pending data");

    console.log("0");

    var date = req.param('date');
    var joblist;
    var vehiclelist;

    console.log("1");

    var promises = [];
    promises.push(query1(date));
    promises.push(query2());

    var results = await Promise.all(promises);
    console.log(results[0]); // query1
    console.log(results[1]); // query2

    res.send('blah');
});

function query1(date) {
    return new Promise((resolve, reject) => {
        res.locals.connection.query('SELECT * FROM job WHERE date = ?',[date] , function (error, results, fields) {
            if (error) {
                reject(error);
            } else {
                resolve(results);
            }
        }
    })
}

function query2() {
    return new Promise((resolve, reject) => {
        res.locals.connection.query('SELECT * FROM vehicle ' , function (error, results, fields) {
            if (error) {
                reject(error);
            } else {
                resolve(results);
            }
        }
    })
}

module.exports = router;