Understanding Callbacks 01May, 2015

I am back with a complicated yet very interesting article on “Callbacks”.

First of all, why do we need callbacks?

Our javascript is synchronous in its behavior. It works only on a single thread. Each statement executes when the earlier statement is executed. Now the case arise, if one statement takes more time to execute, then the next statement will be halted.

For example:

	1. console.log("1");
	2. var result = 0;
	3. for(var i=0; i<=100000; i++){
			result += i;
		}
	4. console.log('3');

So till the time loop doesn’t execute for 100000 statements, it will not execute the 4th statement. But in case we have some event like a ajax call, a file read operation or any other activity than a normal javascript function, then javascript will behave differently.

For example:

	1. console.log("1");
	2. var result = 0;
	3. getdatafromAjax('param1', function(data){
			console.log("here is the result");
		});
	4. console.log('3');

In this case 4th statement will run prior to the 3rd statement. If the execution of the 3rd statement is taking too much time, then this process is added to the thread pool with the callback as a pointer on which the executor will return after completing the task. Further,the output “here is the result” will be printed.

javascript synchronous function call

Callback is not a keyword, but it is only a function just like any normal function. The difference in a normal function and a callback function is that a callback function is called when a normal function completes its execution. For example:

$('.btn').click(function(){
		console.log("button is clicked");
	});

This is a normal function which states that WHEN button is clicked THEN print “button is clicked”. So here the callback function is

function(){
		console.log("button is clicked");
	}

We can do this in a more readable way like (example 1)

	var btnclicked = function(){
		console.log("button is clicked");
	}
	$('.btn').click(btnclicked);

If we work with JQuery while developing our project, then we generally use callbacks, but sometimes we are not aware of the TERM used for the functionality we are developing. In ajax call, we use callbacks when we enter in while entering the success function like

$.ajax({
		url:'someurl.php',
		success: function(data){
			console.log("I am in success function");
		}
	})

Callbacks become very messy if we have to fetch a large hierarchical data which is dependent. For example

1. Fetch user information of id 1.
2. Fetch employer’s information on the basis of user’s employer.
3. Fetch employer’s degree names on the basis of employer’s degree id.

So our client side code will be

$.ajax({
	url : 'someurl/getuserdata',
	data : 'id=1',
	success : function(data){
		console.log("I have got user's data. Now lets get user's employer.");
		$.ajax({
			url : 'someurl/userdata',
			data : 'id='+data.employer,
			success : function(result){
					console.log("I have got employer's data.   Now lets get employer's degree.");
					$.ajax({
						url : 'someurl/getdegrees',
						data : 'id='+result.degreeid,
						success : function(){
						    console.log("I have got user's data. Now lets get user's employer.");
						},
						error:function(){
						       console.log("Hey! i couldn't get employer's degrees.");
						}
					});
			},
			error: function(){
					console.log("Hey! i couldn't get employer's data.");
			}
		});
	},
	error: function(){
		console.log("Hey! i couldn't get user data.");
	}
});

Similarly, if our requirements becomes more dependent, then this loop will go deeper and ultimately, it will give us a “Callback Hell”. So, to resolve the issue of this “Callback Hell”, we use named callbacks just like we did for example 1. In the same way we can write

var myClass = {
	getUser : function(userid, callback){
		// get user information and save that in "user"
		callback(user); // here callbacks returns the data to the original function
	},
	getDegress : function(degreeid, next){
		// get degree from db and return to the original function
		next(degree);
	}
}
myClass.getUser(1, function(user){
	// get employer's information
	myClass.getUser(user.employer, function(employer){
		myClass.getDegress(employer.degreeid, function(degree){
			console.log("so here we got the degree");
		});
	});
});

So our code becomes more readable now by using the named callback functions.

Hope the above explanation of callbacks usage is helpful. Do post your queries if any.

Posted by: Sandeep Kaur / In: JavaScript and Tagged ,
Cam

Leave a Reply

Your email address will not be published.