I am trying to create a route in Node.js/Express that reads data from two queries and then increments a count based on that data from the queires. Since Node.js is asynchronous my total is displayed before all the data has been read.
I created a simple example that gets to the point of what I am currently doing
var express = require('express');
var router = express.Router();
var total = 0;
/* GET home page. */
router.get('/', function(req, res, next) {
increment(3);
increment(2);
console.log(total);
res.end();
});
var increment = function(n){
//Wait for n seconds before incrementing total n times
setTimeout(function(){
for(i = 0; i < n; i++){
total++;
}
}, n *1000);
};
module.exports = router;
I'm not sure what I would have to do in order to wait until both functions finish before I print the total. Would I have to create a custom Event Emitter to achieve this?
I am trying to create a route in Node.js/Express that reads data from two queries and then increments a count based on that data from the queires. Since Node.js is asynchronous my total is displayed before all the data has been read.
I created a simple example that gets to the point of what I am currently doing
var express = require('express');
var router = express.Router();
var total = 0;
/* GET home page. */
router.get('/', function(req, res, next) {
increment(3);
increment(2);
console.log(total);
res.end();
});
var increment = function(n){
//Wait for n seconds before incrementing total n times
setTimeout(function(){
for(i = 0; i < n; i++){
total++;
}
}, n *1000);
};
module.exports = router;
I'm not sure what I would have to do in order to wait until both functions finish before I print the total. Would I have to create a custom Event Emitter to achieve this?
Share Improve this question asked Mar 4, 2015 at 8:40 dfanndfann 951 gold badge1 silver badge7 bronze badges 1- 2 You pass callbacks. An event emitter would work as well. Or promises. Thinking about the issue as having to "wait" until something is done is wrong. You rather should think about it as "how can I know when X is done in order to run Y". And callbacks, events or promises are all solutions for that problem. – Felix Kling Commented Mar 4, 2015 at 8:43
2 Answers
Reset to default 11Embrace asynchronicity:
var express = require('express');
var router = express.Router();
var total = 0;
/* GET home page. */
router.get('/', function(req, res, next) {
increment(3, function() { // <=== Use callbacks
increment(2, function() {
console.log(total);
res.end();
});
});
});
var increment = function(n, callback){ // <=== Accept callback
//Wait for n seconds before incrementing total n times
setTimeout(function(){
for(i = 0; i < n; i++){
total++;
}
callback(); // <=== Call callback
}, n *1000);
};
module.exports = router;
Or use a promises library, or use events. In the end, they're all asynchronous callback mechanisms with slightly different semantics.
You can use some library like async.
Here is the code:
var total = 0;
/* GET users listing. */
router.get('/', function(req, res) {
async.series([
function(callback){
increment(2, function(){
callback(null, "done");
});
},
function(callback){
increment(3, function(){
callback(null, "done");
});
}
],
function(err, result){
console.log(total);
res.send('respond the result:' + total);
});
});
var increment = function(n, callback){
//Wait for n seconds before incrementing total n times
setTimeout(function(){
for(var i = 0; i < n; i++){
total++;
}
callback();
}, n *1000);
};