setTimeout
is a bit apart from EventEmitter
, due to which you are getting these results. First of all I would ask you to run these examples first.
Save this in async.html and run it in your browser. Check the console to see the results.
<div id="element">
</div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
setTimeout(function(){console.log("Hello")},0);
$("#element").click(function(e){
console.log("Inside");
});
$("#element").click();
for (var i = 0; i < 5; i++) {
console.log('I am loop');
}
</script>
Output
Inside
I am loop
I am loop
I am loop
I am loop
I am loop
Hello
Now save this in async.js and run this in node.js
setTimeout(function(){console.log("Hello")},0);
for (var i = 0; i < 5; i++) {
console.log('I am loop');
}
Output
I am loop
I am loop
I am loop
I am loop
I am loop
Hello
You will find that setTimeout
works a little different than EventEmitter
. An EventEmitter executes the handler immediately whereas setTimeout attempts to execute it immediately. The actions are not performed until the next tick. Read about it here.
Do not mix setTimeout with EventEmitter.
Edit
Your example does not demonstrate asynchrony quite well. You are simply running a loop inside the event handler. Here is a more clear example :
var events = require("events");
var event = new events.EventEmitter();
event.on("work", function (i,cb) {
console.log('Started '+i );
setTimeout(function(){event.emit("done",i,cb);},Math.random()*1000);
});
event.on("done", function (i,cb) {
cb(i);
});
var async = function (cb) {
for (var i = 0; i <= 100; i++) {
emitclosure(i,cb);
}
}
function emitclosure(i,cb){
setTimeout(function(){event.emit("work",i,cb)},Math.random()*1000);
}
async(function (i) {
console.log("I have done "+i);
});
I would point out that I use setTimeout
along with events only to give a feel of delay of arrival of work and processing delay, unlike their synonymous use in the question. emitclosure
is just a closure for loop variables, so that their scope is safe.