[javascript] Getting a better understanding of callback functions in JavaScript

I understand passing in a function to another function as a callback and having it execute, but I'm not understanding the best implementation to do that. I'm looking for a very basic example, like this:

var myCallBackExample = {
    myFirstFunction : function( param1, param2, callback ) {
        // Do something with param1 and param2.
        if ( arguments.length == 3 ) {
            // Execute callback function.
            // What is the "best" way to do this?
        }
    },
    mySecondFunction : function() {
        myFirstFunction( false, true, function() {
            // When this anonymous function is called, execute it.
        });
    }
};

In myFirstFunction, if I do return new callback(), then it works and executes the anonymous function, but that doesn't seem like the correct approach to me.

This question is related to javascript function callback

The answer is


There are 3 main possibilities to execute a function:

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. callback(argument_1, argument_2);
  2. callback.call(some_object, argument_1, argument_2);
  3. callback.apply(some_object, [argument_1, argument_2]);

The method you choose depends whether:

  1. You have the arguments stored in an Array or as distinct variables.
  2. You want to call that function in the context of some object. In this case, using the "this" keyword in that callback would reference the object passed as argument in call() or apply(). If you don't want to pass the object context, use null or undefined. In the latter case the global object would be used for "this".

Docs for Function.call, Function.apply


the proper implementation would be:

if( callback ) callback();

this makes the callback parameter optional..


Here is a basic example that explains the callback() function in JavaScript:

_x000D_
_x000D_
var x = 0;_x000D_
_x000D_
function testCallBack(param1, param2, callback) {_x000D_
  alert('param1= ' + param1 + ', param2= ' + param2 + ' X=' + x);_x000D_
  if (callback && typeof(callback) === "function") {_x000D_
    x += 1;_x000D_
    alert("Calla Back x= " + x);_x000D_
    x += 1;_x000D_
    callback();_x000D_
  }_x000D_
}_x000D_
_x000D_
testCallBack('ham', 'cheese', function() {_x000D_
  alert("Function X= " + x);_x000D_
});
_x000D_
_x000D_
_x000D_

JSFiddle


Callbacks are about signals and "new" is about creating object instances.

In this case it would be even more appropriate to execute just "callback();" than "return new callback()" because you aren't doing anything with a return value anyway.

(And the arguments.length==3 test is really clunky, fwiw, better to check that callback param exists and is a function.)


the proper implementation would be:

if( callback ) callback();

this makes the callback parameter optional..


Callbacks are about signals and "new" is about creating object instances.

In this case it would be even more appropriate to execute just "callback();" than "return new callback()" because you aren't doing anything with a return value anyway.

(And the arguments.length==3 test is really clunky, fwiw, better to check that callback param exists and is a function.)


You can use:

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

The below example is little more comprehensive:

_x000D_
_x000D_
function mySandwich(param1, param2, callback) {_x000D_
  alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);_x000D_
  var sandwich = {_x000D_
      toppings: [param1, param2]_x000D_
    },_x000D_
    madeCorrectly = (typeof(param1) === "string" && typeof(param2) === "string") ? true : false;_x000D_
  if (callback && typeof(callback) === "function") {_x000D_
    callback.apply(sandwich, [madeCorrectly]);_x000D_
  }_x000D_
}_x000D_
_x000D_
mySandwich('ham', 'cheese', function(correct) {_x000D_
  if (correct) {_x000D_
    alert("Finished eating my " + this.toppings[0] + " and " + this.toppings[1] + " sandwich.");_x000D_
  } else {_x000D_
    alert("Gross!  Why would I eat a " + this.toppings[0] + " and " + this.toppings[1] + " sandwich?");_x000D_
  }_x000D_
});
_x000D_
_x000D_
_x000D_


There are 3 main possibilities to execute a function:

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. callback(argument_1, argument_2);
  2. callback.call(some_object, argument_1, argument_2);
  3. callback.apply(some_object, [argument_1, argument_2]);

The method you choose depends whether:

  1. You have the arguments stored in an Array or as distinct variables.
  2. You want to call that function in the context of some object. In this case, using the "this" keyword in that callback would reference the object passed as argument in call() or apply(). If you don't want to pass the object context, use null or undefined. In the latter case the global object would be used for "this".

Docs for Function.call, Function.apply


You can use:

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

The below example is little more comprehensive:

_x000D_
_x000D_
function mySandwich(param1, param2, callback) {_x000D_
  alert('Started eating my sandwich.\n\nIt has: ' + param1 + ', ' + param2);_x000D_
  var sandwich = {_x000D_
      toppings: [param1, param2]_x000D_
    },_x000D_
    madeCorrectly = (typeof(param1) === "string" && typeof(param2) === "string") ? true : false;_x000D_
  if (callback && typeof(callback) === "function") {_x000D_
    callback.apply(sandwich, [madeCorrectly]);_x000D_
  }_x000D_
}_x000D_
_x000D_
mySandwich('ham', 'cheese', function(correct) {_x000D_
  if (correct) {_x000D_
    alert("Finished eating my " + this.toppings[0] + " and " + this.toppings[1] + " sandwich.");_x000D_
  } else {_x000D_
    alert("Gross!  Why would I eat a " + this.toppings[0] + " and " + this.toppings[1] + " sandwich?");_x000D_
  }_x000D_
});
_x000D_
_x000D_
_x000D_


_x000D_
_x000D_
function checkCallback(cb) {_x000D_
  if (cb || cb != '') {_x000D_
    if (typeof window[cb] === 'undefined') alert('Callback function not found.');_x000D_
    else window[cb].call(this, Arg1, Arg2);_x000D_
  }_x000D_
}
_x000D_
_x000D_
_x000D_


There are 3 main possibilities to execute a function:

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. callback(argument_1, argument_2);
  2. callback.call(some_object, argument_1, argument_2);
  3. callback.apply(some_object, [argument_1, argument_2]);

The method you choose depends whether:

  1. You have the arguments stored in an Array or as distinct variables.
  2. You want to call that function in the context of some object. In this case, using the "this" keyword in that callback would reference the object passed as argument in call() or apply(). If you don't want to pass the object context, use null or undefined. In the latter case the global object would be used for "this".

Docs for Function.call, Function.apply


_x000D_
_x000D_
function checkCallback(cb) {_x000D_
  if (cb || cb != '') {_x000D_
    if (typeof window[cb] === 'undefined') alert('Callback function not found.');_x000D_
    else window[cb].call(this, Arg1, Arg2);_x000D_
  }_x000D_
}
_x000D_
_x000D_
_x000D_


Callbacks are about signals and "new" is about creating object instances.

In this case it would be even more appropriate to execute just "callback();" than "return new callback()" because you aren't doing anything with a return value anyway.

(And the arguments.length==3 test is really clunky, fwiw, better to check that callback param exists and is a function.)


There are 3 main possibilities to execute a function:

var callback = function(x, y) {
    // "this" may be different depending how you call the function
    alert(this);
};
  1. callback(argument_1, argument_2);
  2. callback.call(some_object, argument_1, argument_2);
  3. callback.apply(some_object, [argument_1, argument_2]);

The method you choose depends whether:

  1. You have the arguments stored in an Array or as distinct variables.
  2. You want to call that function in the context of some object. In this case, using the "this" keyword in that callback would reference the object passed as argument in call() or apply(). If you don't want to pass the object context, use null or undefined. In the latter case the global object would be used for "this".

Docs for Function.call, Function.apply


You should check if the callback exists, and is an executable function:

if (callback && typeof(callback) === "function") {
    // execute the callback, passing parameters as necessary
    callback();
}

A lot of libraries (jQuery, dojo, etc.) use a similar pattern for their asynchronous functions, as well as node.js for all async functions (nodejs usually passes error and data to the callback). Looking into their source code would help!


Here is a basic example that explains the callback() function in JavaScript:

_x000D_
_x000D_
var x = 0;_x000D_
_x000D_
function testCallBack(param1, param2, callback) {_x000D_
  alert('param1= ' + param1 + ', param2= ' + param2 + ' X=' + x);_x000D_
  if (callback && typeof(callback) === "function") {_x000D_
    x += 1;_x000D_
    alert("Calla Back x= " + x);_x000D_
    x += 1;_x000D_
    callback();_x000D_
  }_x000D_
}_x000D_
_x000D_
testCallBack('ham', 'cheese', function() {_x000D_
  alert("Function X= " + x);_x000D_
});
_x000D_
_x000D_
_x000D_

JSFiddle


You should check if the callback exists, and is an executable function:

if (callback && typeof(callback) === "function") {
    // execute the callback, passing parameters as necessary
    callback();
}

A lot of libraries (jQuery, dojo, etc.) use a similar pattern for their asynchronous functions, as well as node.js for all async functions (nodejs usually passes error and data to the callback). Looking into their source code would help!


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to function

$http.get(...).success is not a function Function to calculate R2 (R-squared) in R How to Call a Function inside a Render in React/Jsx How does Python return multiple values from a function? Default optional parameter in Swift function How to have multiple conditions for one if statement in python Uncaught TypeError: .indexOf is not a function Proper use of const for defining functions in JavaScript Run php function on button click includes() not working in all browsers

Examples related to callback

When to use React setState callback How to send an HTTP request with a header parameter? javascript function wait until another function to finish What is the purpose of willSet and didSet in Swift? How to refactor Node.js code that uses fs.readFileSync() into using fs.readFile()? Aren't promises just callbacks? How do I convert an existing callback API to promises? How to access the correct `this` inside a callback? nodeJs callbacks simple example Callback after all asynchronous forEach callbacks are completed