【问题标题】:How to wait for data before next execution in node.js如何在 node.js 中的下一次执行之前等待数据
【发布时间】:2019-04-30 02:39:01
【问题描述】:

如何在 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;

【问题讨论】:

    标签: node.js express server


    【解决方案1】:

    问题在于:

    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

    根据后续评论快速 sn-p:(它不是完全工作的代码,只是概念的一个示例)

    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;
    

    【讨论】:

    • 对于您的解决方案就像我必须等待第一个查询然后运行第二个查询然后运行我的执行,但我需要的是同时运行第一个和第二个查询然后在第一次运行 jar 文件时执行第二个查询数据返回
    • 这是你需要使用 Promise 的地方。将所有数据库查询封装在返回 promise 的函数中,将它们放入 promise 数组中,然后运行 ​​var results = await Promise.all(array);
    • 我为此添加了一个 sn-p。但这包含了很多概念。你将不得不阅读回调、承诺、异步/等待,特别是 Promise.all()。在您对所有这些都感到满意之前,我可能会考虑您需要多少才能同时获得这两个调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    • 2021-02-12
    • 2014-07-30
    • 2020-12-21
    • 2019-12-31
    • 1970-01-01
    相关资源
    最近更新 更多