Reputation: 6797
I'm having a bit of trouble understanding the mechanics of JS callbacks. I have a fair idea of how callbacks can be used in JS, but I do not understand how a callback is asynchronous.
For e.g., if my understanding is correct, a callback is of the nature:
db.query(param1, param2 , callback_fn1(){..} );
And the implementation of db.query() is along the lines of :
db.prototype.query = function(p1 , p2 , callback ){
//some code
callback();
}
How does the above implementation make db.query
an asynchronous function? Does this not mean that a function called callback
is passed to query
and that function is called inside query
? It looks like query
is just another synchronous function. Could someone help me understand what I'm overlooking here? Thanks!
Upvotes: 0
Views: 227
Reputation: 91619
The code sample you've shown is actually still synchronous because is instructed to run immediately. An asynchronous callback is a callback that doesn't immediately need to be executed, so it doesn't block the event loop until you instruct it to run.
The most common way in Node.js to do this is with process.nextTick()
which runs a specified function when the event loop call stack is empty. Here's an example:
var async = function(args, callback) {
// do some work
process.nextTick(function() {
callback(val);
});
};
Then we call the function like this:
async(args, function(val) {
console.log(val);
});
console.log('end');
In this example, the function async()
and console.log('end')
are added to the call stack. The call stack empties once both of those functions are run, and once it's empty, console.log(val)
then runs.
If you're still confused, think of process.nextTick()
as an optimized version of this code:
var fn = function() {};
setTimeout(fn, 0);
It basically means "run this function as soon as possible when you are not busy".
Upvotes: 3
Reputation: 20033
Edit: I just now realized the question is tagged with node.js. My answer is more about Javascript in the browser, @hexacyanide's answer is more about node.js. I guess knowing both doesn't hurt, though!
The way you posted it the code will indeed be blocking. For asynchronous behavior there are a few things you can utilize, such as
setTimeout
and setInterval
FileReader
APIYour example code could be written as follows (fiddle):
function doStuff(callback) {
setTimeout(function () {
for (var i = 0; i < 1000; i++) {
// do some busy work
var x = Math.sqrt(i);
}
callback();
}, 0);
}
console.log('start');
doStuff(function () {
console.log('callback called');
});
console.log('after doStuff()');
The setTimeout
call will allow the Javascript interpreter/compiler (however exactly they work these days) to run the function in a non-blocking matter which is why (most likely), you will see the output
start
after doStuff()
callback called
Note that asynchronousity is different from multi-threading. Javascript is still single-threaded (with the exception of web workers!).
A more in-depth explanation can be found for example here
Upvotes: 2