In your code, callback is executed on the same event loop iteration as foreach itself. As you never go outside of the current event loop iteration, buf += "finished" only executes after all buf += item were executed.
The proper version is
var ASync = require('async');
var arr = [];
for (var i = 0; i< 10; i++) {
arr[i] = i;
}
var buf = "howdy";
ASync.forEach(arr, function(item, callback) {
process.nextTick(function () {
buf += item;
callback();
});
}, function(err) {
console.log(buf); // in the end
});
buf += "finished";
In the end, the buf will equal to howdy0finished123456789.
However, this task is oversimplified. Why does one need the async loop at all?
To perform async tasks in parallel. First, as each task is async, you won't trigger the callback in the same event loop iteration anyway, rather giving it to the specific async task. Second, async.parallel is more suitable for this kind of task.
To perform some CPU-intensive tasks, avoiding freezing the event loop (so that Node could process some tasks in between the iterations). This is what I'm assuming in my code example above. It would be quite hard to achieve this task using the plain JS (and its build-in Array.prototype.forEach), as you need to implement in some way the detection of the event all iterations of the loop has been processed.
setTimeout(...,0)workaround to hand back execution to the main event loop but I really don't like the idea - going that way you could actually use JS' built-inArray.forEachmethod anyway. Besides, I'd expect that the Async module would do that if necessary and hide those details from me.