CodeinWP CodeinWP

Callback Functions in JavaScript

Callback Functions in JavaScriptIf you’re fairly inexperienced with JavaScript but you’ve used jQuery, then its likely you’ve used callback functions. But maybe you don’t fully understand how they work or how they’re implemented.

In this post, which is based on what I’ve learned about callback functions in JavaScript, I’ll try to enlighten you on this fairly common technique. If you have anything to add, feel free to post a comment.

What is a Callback Function?

The above-linked Wikipedia article defines it nicely:

A reference to executable code, or a piece of executable code, that is passed as an argument to other code.

Here’s a simple example that’s probably quite familiar to everyone, taken from jQuery:

$('#element').fadeIn('slow', function() {
  // callback function

This is a call to jQuery’s fadeIn() method. This method accepts two arguments: The speed of the fade-in and an optional callback function. In that function you can put whatever you want.

When the fadeIn() method is completed, then the callback function (if present) will be executed. So, depending on the speed chosen, there could be a noticeable delay before the callback function code is executed. You can read more about jQuery’s callback functions here.

How to Write a Callback Function

If you’re writing your own functions or methods, then you might come across a need for a callback function. Here’s a very simple example of a custom callback function:

function mySandwich(param1, param2, callback) {
  console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2);

mySandwich('ham', 'cheese', function() {
  console.log('Finished eating my sandwich.');

Here we have a function called mySandwich and it accepts three parameters. The third parameter is the callback function. When the function executes, it spits out an alert message with the passed values displayed. Then it executes the callback function.

Notice that the actual parameter is just “callback” (without parentheses), but then when the callback is executed, it’s done using parentheses. You can call this parameter whatever you want, I just used “callback” so it’s obvious what’s going on.

The callback function itself is defined in the third argument passed to the function call. That code has another alert message to tell you that the callback code has now executed. You can see in this simple example that an argument passed into a function can be a function itself, and this is what makes callbacks possible in JavaScript.

Here’s a CodePen that uses the simple example above:

Make Callback Functions in JavaScript Optional

One thing you’ll notice about jQuery callbacks is that they’re optional. This means if a method accepts a callback, it won’t return an error if a callback is not included. In our simple example, the page will return an error if we call the function without a callback, like this:

function mySandwich(param1, param2, callback) {
  console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2);

// Missing required argument. Check the browser's developer tools for the error message: Uncaught TypeError: callback is not a function at mySandwich
mySandwich('ham', 'cheese');

If you look at the console, you’ll see an error that says “Uncaught TypeError: callback is not a function” (or something similar) that appears after the initial console message.

To make the callback optional, we can just do this:

function mySandwich(param1, param2, callback) {
  console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2);
  if (callback) {

// No third argument, but no error because we check for the callback first.
mySandwich('ham', 'cheese');

Now, since we’re checking to ensure the existence of callback, the function call won’t cause an error without it.

Make Sure the Callback is a Function

Finally, you can ensure that whatever value is passed as the third argument is in fact a proper function, by doing this:

function mySandwich(param1, param2, callback) {
  console.log('Started eating my sandwich. It has: ' + param1 + ', ' + param2);
  if (callback && typeof(callback) === 'function') {

// Third argument is not a function
mySandwich('ham', 'cheese', 'vegetables');

Notice that the function now includes a test using the typeof operator, to ensure that whatever is passed is actually a function. The function call has a third argument passed, but it’s not a function, it’s a string. So the test using typeof ensures no error occurs.

The CodePen below has a non-function argument passed as the callback.

A Note About Timing When Using Callback Functions in JavaScript

Although it is true that a callback function will execute last if it is placed last in the function, this will not always appear to happen. For example, if the function included some kind of asynchronous execution (like an Ajax call or an animation), then the callback would execute after the asynchronous action begins, but possibly before it finishes.

Here’s an example that uses jQuery’s animate() method:

function mySandwich(param1, param2, callback) {
  console.log('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);

    opacity: 0
  }, 5000, function() {
    console.log('Animation complete!');

  if (callback && typeof(callback) === "function") {

mySandwich('ham', 'cheese', function() { 
  console.log('Finished eating my sandwich.');

Notice that although the callback appears later in source order than the animation, the callback will actually execute long before the animation completes. In this case, solving this problem is easy: You just put the callback execution inside the animate method’s callback function (where it says “Animation complete”).

This doesn’t cover all the details regarding asynchronous functions, but it should serve as a basic warning that callback functions will only execute last as long as all the code in the function is synchronous.


Understanding how callback functions in JavaScript work is a nice technique to add to your collection of JavaScript design patterns. I hope this summary of callbacks helps you to understand this concept better. If you have anything technical to add, feel free to post a comment below.

103 Responses

  1. Tyron says:

    When I need to wait on multiple animates’ calbacks or ajax requests, inside the function that calls the callback (i.e. mySandwich), I tend to use Deferred objects to sync all those timings. I’ve modified your example to include this:

  2. This should also work.

    (callback && typeof(callback) === "function") && callback();
    • CallBack says:

      Why complicating…?

      • I agree. Some people find that type of notation clear, but I don’t. I like to be able to read what something does almost instantly, and that syntax just doesn’t work for me. But I know it does for some people, so that’s their preference, no problem

      • Jack Scotty says:

        I agree, just seems to complicate things really. But, again, I agree… it’s a personal preference.

    • Javid says:

      Does it solve any specific purpose. I think more writing causes more typos and hence more bugs. Please add if it helps more, other than as mentioned in Original Post.

    • Calvin says:

      My oh my… Don’t ever write these kinds of codes. Sure this one liner makes sense because it’s condensing a simple logic. If you condense more complicated logic, many people will not know what you were trying to do, and along the way you might even forget.

  3. Jamie says:

    Great write up mate, long time javascript user but never actually figured out how callback methods worked, only recently have I needed to write my own custom callbacks!

  4. Fredrik says:

    Awesome. Was thinkin’ about this just the other day.

  5. Dean Pugh says:

    I’ve tried this before when I needed it for another project but never managed to get it working. At the time I could only find examples of people adding callbacks to plugins.

    This will come in handy in the future and I have booked marked this page for reference! Thanks for such a simple, yet powerful and useful article.

  6. James Newell says:

    This is a really good writeup. I like that you include the bit about asynchronous calls because that is something that can be maddening until you first begin to understand the concept at work.

    One thing you may want to discuss is using a specific method signature with a callback (more often referred to as a delegate, but basically the same thing) to allow for callbacks that take parameters. For example, to receive a more detailed response about the type of sandwich you could do the following:

    function mySandwich(param1, param2, callback) {
      alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
        opacity: 0
      }, 5000, function() { 
        // Animation complete.
      if (callback && typeof(callback) === "function") {  
        callback(param1, param2);  
    mySandwich('ham', 'cheese', function(callbackParam1, callbackParam2) {  
      alert('Finished eating my ' + callbackParam1 + ' & ' + callbackParam2 + ' sandwich.');  
  7. Jeremy Hill says:

    I think another good example would be how to run a callback that receives arguments and has ‘this’ set to something other than the global object. i.e.:

    function mySandwich(param1, param2, callback) {
      alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
      var sandwich = {toppings: [param1, param2]},
        madeCorrectly = (typeof(param1) === "string" && typeof(param2) === "string") ? true : false;
      if (callback && typeof(callback) === "function") {  
        callback.apply(sandwich, [madeCorrectly]);  
    mySandwich('ham', 'cheese', function(correct) {
      if (correct) {
        alert("Finished eating my " + this.toppings[0] + " and " + this.toppings[1] + " sandwich.");
      } else {
        alert("Gross!  Why would I eat a " + this.toppings[0] + " and " + this.toppings[1] + " sandwich?");
  8. Under “Make Sure the Callback is a Function” you just need to do this

    if (typeof callback === "function") callback();

    Checking if it’s defined & a function is an extra, unneeded step.

  9. Thanks for the post. Already coming up with ideas to use callbacks in my code. Wish I had read this post 2 projects ago, would have saved me some time.

  10. Great write up mate, long time JavaScript user but never actually figured out how callback methods worked, thanks for shearing!

  11. John says:

    This looks great and easy. Thanks for the examples. I still have problems implementing it here:

     * Copyright 2010 Nicholas C. Zakas. All rights reserved.
     * BSD Licensed.
    function CrossDomainStorage(origin, path) {
      this.origin = origin;
      this.path = path;
      this._iframe = null;
      this._iframeReady = false;
      this._queue = [];
      this._requests = {};
      this._id = 0;
    CrossDomainStorage.prototype = {
      // restore constructor
      constructor: CrossDomainStorage,
      // public interface methods
      init: function(){
        var that = this;
        if (!this._iframe){
          if (window.postMessage && window.JSON && window.localStorage){
            this._iframe = document.createElement("iframe");
   = "position:absolute;width:1px;height:1px;left:-9999px;";
            if (window.addEventListener){
              this._iframe.addEventListener("load", function(){ that._iframeLoaded(); }, false);
              window.addEventListener("message", function(event){ that._handleMessage(event); }, false);
            } else if (this._iframe.attachEvent){
              this._iframe.attachEvent("onload", function(){ that._iframeLoaded(); }, false);
              window.attachEvent("onmessage", function(event){ that._handleMessage(event); });
          } else {
            throw new Error("Unsupported browser.");
        this._iframe.src = this.origin + this.path;
      requestValue: function(key, callback){
        var request = {
          key: key,
          id: ++this._id
        data = {
          request: request,
          callback: callback
        if (this._iframeReady){
        } else {
        if (!this._iframe){
      // private methods
      _sendRequest: function(data){
        this._requests[] = data;
        this._iframe.contentWindow.postMessage(JSON.stringify(data.request), this.origin);
      _iframeLoaded: function(){
        this._iframeReady = true;
        if (this._queue.length){
          for (var i=0, len=this._queue.length; i < len; i++){
          this._queue = [];
      _handleMessage: function(event){
        if (event.origin == this.origin){
          var data = JSON.parse(;
          this._requests[].callback(data.key, data.value);
          delete this._requests[];
    var remoteStorage = new CrossDomainStorage("", "/server.html");
    remoteStorage.requestValue("something", function(key, value) {
      alert("The value for '" + key + "' is '" + value + "'");
    alert ("I want to access value here! " + value);

    I’ve been told that to use value in alert I need something like a callback but I cannot implant it for this…

    • Rob says:

      Don’t use an anonymous function

      function(key, value){ alert(“The value for ‘” + key + “‘ is ‘” + value + “‘”); })

      but rather a separate stand-alone function

      function myAlertFunction(key, value) { alert(“The value for ‘” + key + “‘ is ‘” + value + “‘”); }

      which you then call as:

      remoteStorage.requestValue(“something”, myAlertFunction(key, value));

      Function closure will (should!) guarantee that you see your key/value values.

  12. david says:

    Thanks a bunch, very useful article :)

  13. Travis Sun says:

    I was just looking for the definition of a callback function and I found this! Awesome post!

  14. I just found this, which looks quite relevant to this discussion:

  15. javabeginner1 says:

    Thanks a lot…
    This post helped me to understand what callback functions are…
    keep up the good work

  16. Akshay says:

    I am new to javascript world. This was really helpful. thx.

  17. excellent article. Great help to OO developers playing round with JS

  18. Tom says:

    Thnx! I learned something today :D

  19. Zee says:

    Fantastic work on breaking this all down Louis.

    We’ll be sending our newbie JS developers to this page to help them understand the basics of callbacks!

  20. trung says:

    Now, I can use callback in javascript.

  21. Luke says:

    Best write-up about callbacks on the net. Ever. Kudos to you.

    This thread tells you why:

  22. Cesar says:

    Excelent article, it helps me a lot!

  23. Much heavier content in this one, but relevant to those considering heavy use of nested callbacks:

  24. Sam Johnson says:

    Much obliged for this. Trying to sort out callbacks from the FileReader object. This article was very helpful for that.

  25. Neo An says:

    Simple but clearly and really great!
    Thanks :)

  26. ashok says:

    short and sweet……thanks

  27. Jeffrey van Ham says:

    Just what I was looking for! Jquerymobile refresh listview and selectmenu Need a callback function for this after dynamically creating them. Thanks!

  28. ABname says:

    Extremely Helpful !!

  29. Najeeb says:

    Perfect was thinking about this lately and you explained it nicely.

    Good Job

  30. Kunal says:

    It was indeed very helpful for a someone like me who is new to js…..
    Many thanks

  31. Nan Zhang says:

    In javascript, the callback definition you quoted on wikipedia is confusing, I found it gave me the better understanding: “A callback function (in jquery) is executed after the current effect is 100% finished”. in w3schools.

    Your callback example is clear and easy to follow, but in practice, it’s the same effect to put all codes in order in a javascript file. For example, I trid to load a css file before showing a form in javascript, I would have the same effect to use callback function you suggested or to put all codes in order without the function. However, the solution is suggested this post “”, binding event onreadystatechange or onload to the callback function. It works for me.

    • Yes, you’re right, JS lines will load in order of appearance. However, as I understand things, the new lines that run don’t wait for the previous lines to finish. So in some cases (as in the case of a long animated effect like a fade out), you need a callback to ensure the previous code is completely finished before loading the next line.

      So while in some cases you can get away with one line after another, there are other cases where you absolutely need the previous code to finish first, in which case you need a callback.

  32. Rick says:

    Very easy to understand. Thank you for your informative content.

  33. Shan says:

    thanks a lot :)

  34. Jack Albright says:

    Very helpful post. Thanks a lot. My understanding of Javascript just went up a notch.

  35. daniel says:


    function thankyou(callback) {
      alert('thank you!');
    thankyou(function() {
      alert('your the best!');
  36. Chris says:

    One of the best articles I’ve read. I went from being confused about how to create a callback function to understanding the concept fully in about 20 seconds flat. Thanks :)

  37. satish says:


  38. Shiham says:

    Thanks, great information to remind things even if you already read about callback :)

  39. Japo Domingo says:

    Thank you. I’m fairly new with both JS and JQuery so before reading this post I found callback functions quite magical. :D I keep forgetting to treat functions as objects/variables as well.

  40. Ibrahim Islam says:

    Thanks for this introductory lesson, mate

  41. Taiwan says:

    Thank you. Very useful article.

  42. Mohammed says:

    Saved my day !

  43. vive says:

    very nice article

  44. Alex says:

    Thanks. I use your example when explaining Callbacks to those not familiar with it.

  45. Hardik Sodha says:

    Good and easy to understand artical. Thanks for sharing.

  46. Mr.Black says:

    Thank God!!. You saved me!!

    Great Tutorial that I’ve ever seen on javascript callback.
    Easy to understand. Impressive~!!

    Again, I really appreciate your GREAT Effort!!

  47. Flavio says:

    Hi Luis,

    I would like to know why a callback function such:

    $.get('view/template.html', function(d) {
      tmpl = d;

    Don’t works inside another function, as in the example bellow:

    function renderRecords(transaction, results) {
      var tmpl;
      $.get('view/template.html', function(d) {
        tmpl = d;

    On the above example the tmpl variable is never loaded, even knowing the “d” variable has the content, because it is shown in the alert box.

    I’ve worked around it calling “$.get” outside the scope of the function, to previously load the variable tmpl, and then use it inside the function, but I would like to understand what happened and why.

    Best Regards,


  48. Łukasz says:

    awesome post, read a few on this subject that didn’t make much sense. Guess more examples have to be about lunch :)

  49. Gerd says:


    great, well written article. But what do you do if your callback function is not only a function but a method of a certain object?
    How do you define (if necessary) and pass this object along with its callback method to your function?
    Reason for asking: I will have to call a function in a framework which demands a callback object. Inside this function, the callback object’s method onCompletion(param1,param2) will be called.
    How can I get hold of param1 and param2?

    Thank you very much in advance.

    • I think you could just do something like this:

      // code here with function as method defined
      function mySandwich(param1, param2, callback) {
        alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
        callback(methodparam1, methodparam2);
      mySandwich('ham', 'cheese', mainObject.callback(mp1, mp2) {
        alert('Finished eating my sandwich.');

      I might be wrong though, you’d have to test it. Notice I’ve added params for the callback reference. Again, I’m not 100% sure this is what you want, but in theory I believe this should work.

      • anon says:

        you can use a closure to pass the function with parameters

        function mySandwich(param1, param2, callback) {
          alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);
        var var1 = "first argument";
        var var2= "second argurment";
        var mainObject = { callback: function(arg1, arg2) {
            alert("arg1=" + arg1 + " and arg2=" + arg2);
        mySandwich('ham', 'cheese', function() {
          mainObject.callback(var1, var2);
  50. Manjunath says:

    You made my life easier.I found this place perfect to learn about CALLBACKS :)

  51. Bruce says:

    This was a great article – very clear, I now know how to use callbacks!

  52. Prabodh Meshram says:

    Awesome Post man !!! helped me to pick up with the basics for the callback Concept. keep the great work Going !! Thanks

  53. twstfy says:

    Thanks. For some reason I was struggling with Javascript callbacks – this post cleared it up.

  54. You have my thanks, too. Cleanest article to explain JS callbacks at the moment. That CallbackHell comment is also useful.

  55. Gino says:

    Thank you!

  56. Anonymous says:

    Surely the clearest and simplest tutorial for callback() functions on the whole internet.
    I’m going to add your website in the “Must Read” zone of my Favourites! ;)

  57. Siamak says:

    Great article. Thanks, helped me.
    But for timing you can do it like this:

    var myFunc = function (name, time, callback) {
      alert('hi '+name);
      if(callback){ setTimeout(callback,time); }
    myFunc('siamak', 200, function() {
  58. hugo says:

    Wow I was so confused about callbacks and it really helped me. Thanks

  59. neil says:

    I would agree that this is the best write-up I have seen regarding callbacks. However, now that I understand it better, why would you not just call the subsequent functions directly and remove the entire callback process. For instance, using callbacks I could process three steps with the following:

    function myfunction1() {
      alert("We are in myfunction1");
      myfunction2('ham1', 'cheese2', myfunction3); 
    function myfunction2(param1, param2, callback) {  
      alert("We are in myfunction2");
      // Do some processing...
      if (callback && typeof(callback) === "function") {
    function myfunction3() {
      alert("We are done processing.");

    However, why is this any different than the following?

    function myfunction1() {
      alert("We are in myfunction1");
      myfunction2('ham1', 'cheese2'); 
    function myfunction2(param1, param2) {  
      alert("We are in myfunction2");
      // Do some processing...
    function myfunction3() {
      alert("We are done processing.");

    I do see the possibility of changing the step sequence by dynamically changing the function calls using callbacks. But, if I want to process multiple functions in a certain sequence, why can’t I just call tham as explained above?

    • In my examples, I don’t think there is any difference from yours. Mainly, callbacks are beneficial when you’re dealing with processes that could ‘block’ other stuff from happening. See the explanation here:

      Callbacks are great when dealing with asynchronous actions (usually Ajax or animations), so you can still run other code on the page without blocking anything else, and when the asynchronous action completes, you’ll get a ‘notice’ when it’s done, via the callback.

      Probably I could write a separate article explaining this, because now that I look at my code above, it is pretty simple and isn’t exactly the ideal use case for callbacks.

  60. Rafa says:

    Hi Louis,
    I’m learning Javascript and I’m getting crazy with a case.
    I´ve got some calls on my html code to a function just like this:
    ‘ onclick=”fisrt(1)” onclick=”fisrt(2)” ‘ …

    And my js look like this:

    Function first(case) {
      if (condition) {
        switch (case) {
        case 1:
        case 2:
      } else {

    So I need function first() to wait function second() to finish if the condition is met.

    I hope you can help me and thanks in advanced.

  61. Radovan Svedic says:

    Nice article.

    However, why wouldn’t one use the following approach:

    function mySandwich(param1, param2, callback) {
      callback = typeof callback === 'function' ? callback : function() {};
      the rest of your code

    it’s a bit annoying to have that line on top of every function expecting an optional callback but that way your callback calls are free of any also annoying checks for callback existence, wherever they may appear and regardless of how many times.

    Thoughts? Is there any good reason to avoid this construction?

    • Your code is probably better. Generally, when I write JS, I’m a bit overly-precise on clarity of code. I find the code you used to be a bit confusing at first glance, so for tutorials (and even my own projects) I prefer a more explicit approach.

      But for sure, yours seems to be much more efficient, and I don’t see any problems with it. :)

  62. saibaba says:

    nice article ! its very clear to be understood by a beginner . Thank you !!

  63. Ting says:

    Very comprehensive post– I especially liked how you put HTML + jQuery + Callbacks together using the JSBin. It really helps me tie together how each of elements fit together :)

  64. Tirthraj Barot says:

    How can we return values by callback functions?

  65. Berguiga says:

    thank you for your post

  66. John Crosskey says:

    Your post was a long time ago but I am extremely grateful for your clear and simple explanation of actually writing a callback function. I come from Pascal and Javascript is weird and exciting. I have listened to lectures by Douglas Crockford but the real clincher is the coder who says, here this is how you actually write it.


  67. Ace says:


    Many thanks for this article, I#m trying to get my iOS app to show imageName. This is my function

    function getImageURL(object, callback) {
      var imageURL;
      object.onScreenshotReady(function(imageName) {

    on iOS, i do:

    let script = "getImageURL(widget, function() { imageName })"
    let returnedResults = webView.stringByEvaluatingJavaScriptFromString(script)

    The function executes because the alert with the correct imageName appears.

    I just can’t get that name to my iOS app. iOS uses actually wants the last value in getImageURL and thats what results become.

  68. Alex says:

    Thank you!!! After reading so many sites about this topic, I finally found the one I needed to understand it.

  69. Paul says:

    good post! best one I have read on callbacks yet!

  70. Shivani says:

    Awesome explanation,have searched whole web but this one cleared the basic concept of callback function.
    Thanks a ton :)

  71. Allgreeen says:

    Perfect article !

  72. Rohit says:

    Thanks a lot for this perfect article.

  73. Allan says:

    Good forum, I was sent here by OneSignal, I wanna try to make out the callback function in Javascript.
    Thanks since from now.
    Congratulations to all.

  74. Jonathan says:

    Great post. Very clear explanation of callback

  75. sandeep says:

    Nice but i need to return a result after completed web services calling. Please help me.

  76. Bryan says:

    Clear, concise, and heavily example-laden explanation. Thank you!

  77. Tr says:

    Thanks A lot Sir

  78. OS says:

    Thank you so much for this. I’ve been trying to wrap my head around these as self-taught JS and now I finally get it, implemented it and it works :)

    Thanks again!

  79. Jakki says:

    I know this is an old article but it holds up so well – it is by far the best one I’ve read yet on understanding how callbacks work, especially to newbies like me who have little understanding of JS. You actually just helped me code my first real callback function with AJAX so cannot thank you enough!

  80. Hi Louis, thanks for your invaluable article about callback function. I especially liked that you mentioned the point about “Make sure the callback is a function”. We, Javascript developers, works with callbacks a lot. If we remember this point while working, we will be able to write a clean error-free code.

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field and deep URLs are not allowed in the "Website" field. If you use keywords or deep URLs, your comment or URL will be removed. No foul language, please. Thank you for cooperating.

Markdown in use! Use `backticks` for inline code snippets and triple backticks at start and end for code blocks. You can also indent a code block four spaces. And no need to escape HTML, just type it correctly but make sure it's inside code delimeters (backticks or triple backticks).