Reputation: 369
How to wait for data before run the next execution in node.js. For example, I have 3 parts need to be executed. Collect data from job table, collect data from vehicle table then run my jar file. So the current output of console is 0->1->3->5->7->2->4->6
. How to make it like 0->1->3->2->4->5->6->7
. I want to wait for data from first and second query then run the jar file.
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;
Upvotes: 0
Views: 799
Reputation: 1935
The issue is that the following:
function (error, results, fields) {
console.log("2");
if (error) throw error;
joblist = JSON.stringify(results);
}
is a callback function. You're passing that function in your query()
call, and telling it to execute the function when it's finished executing the query. As soon as your code has requested that query (not executed it), it immediately goes on to execute the next code.
In earlier days, the solution to this would be to define all later actions inside that callback function, as roughly such:
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;
Modern JS now has promises, and async/await, which are generally accepted as nicer replacements for callbacks in asynchronous code: https://javascript.info/async-await
Quick snippet as per follow-up comment: (It's not fully working code, just an example of the concepts)
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;
Upvotes: 2