Create a custom callback in JavaScript

JavascriptCallback

Javascript Problem Overview


All I need to do is to execute a callback function when my current function execution ends.

function LoadData() 
{
    alert('The data has been loaded');
    //Call my callback with parameters. For example,
    //callback(loadedData , currentObject);
}

A consumer for this function should be like this:

object.LoadData(success);

function success(loadedData , currentObject) 
{
  //Todo: some action here 
}

How do I implement this?

Javascript Solutions


Solution 1 - Javascript

Actually, your code will pretty much work as is, just declare your callback as an argument and you can call it directly using the argument name.

The basics
function doSomething(callback) {
    // ...

    // Call the callback
    callback('stuff', 'goes', 'here');
}

function foo(a, b, c) {
    // I'm the callback
    alert(a + " " + b + " " + c);
}

doSomething(foo);

That will call doSomething, which will call foo, which will alert "stuff goes here".

Note that it's very important to pass the function reference (foo), rather than calling the function and passing its result (foo()). In your question, you do it properly, but it's just worth pointing out because it's a common error.

More advanced stuff

Sometimes you want to call the callback so it sees a specific value for this. You can easily do that with the JavaScript call function:

function Thing(name) {
    this.name = name;
}
Thing.prototype.doSomething = function(callback) {
    // Call our callback, but using our own instance as the context
    callback.call(this);
}

function foo() {
    alert(this.name);
}

var t = new Thing('Joe');
t.doSomething(foo);  // Alerts "Joe" via `foo`

You can also pass arguments:

function Thing(name) {
    this.name = name;
}
Thing.prototype.doSomething = function(callback, salutation) {
    // Call our callback, but using our own instance as the context
    callback.call(this, salutation);
}

function foo(salutation) {
    alert(salutation + " " + this.name);
}

var t = new Thing('Joe');
t.doSomething(foo, 'Hi');  // Alerts "Hi Joe" via `foo`

Sometimes it's useful to pass the arguments you want to give the callback as an array, rather than individually. You can use apply to do that:

function Thing(name) {
    this.name = name;
}
Thing.prototype.doSomething = function(callback) {
    // Call our callback, but using our own instance as the context
    callback.apply(this, ['Hi', 3, 2, 1]);
}

function foo(salutation, three, two, one) {
    alert(salutation + " " + this.name + " - " + three + " " + two + " " + one);
}

var t = new Thing('Joe');
t.doSomething(foo);  // Alerts "Hi Joe - 3 2 1" via `foo`

Solution 2 - Javascript

It is good practice to make sure the callback is an actual function before attempting to execute it:

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

Solution 3 - Javascript

My 2 cent. Same but different...

<script>
	dosomething("blaha", function(){
		alert("Yay just like jQuery callbacks!");
	});


	function dosomething(damsg, callback){
		alert(damsg);
		if(typeof callback == "function") 
		callback();
	}
</script>

Solution 4 - Javascript

function loadData(callback) {
    
    //execute other requirement

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

loadData(function(){

   //execute callback

});

Solution 5 - Javascript

   function callback(e){
      return e;
   }
    var MyClass = {
       method: function(args, callback){
          console.log(args);
          if(typeof callback == "function")
          callback();
       }    
    }

==============================================

MyClass.method("hello",function(){
    console.log("world !");
});

==============================================

Result is:

hello world !

Solution 6 - Javascript

Some of the answers, while correct may be a little tricky to understand. Here is an example in layman's terms:

var users = ["Sam", "Ellie", "Bernie"];

function addUser(username, callback)
{
    setTimeout(function()
    {
        users.push(username);
        callback();
    }, 200);
}

function getUsers()
{
    setTimeout(function()
    {
        console.log(users);
    }, 100);
}

addUser("Jake", getUsers);

The callback means, "Jake" is always added to the users before displaying the list of users with console.log.

Source (YouTube)

Solution 7 - Javascript

If you want to execute a function when something is done. One of a good solution is to listen to events. For example, I'll implement a Dispatcher, a DispatcherEvent class with ES6,then:

let Notification = new Dispatcher()
Notification.on('Load data success', loadSuccessCallback)

const loadSuccessCallback = (data) =>{
   ...
}
//trigger a event whenever you got data by
Notification.dispatch('Load data success')

Dispatcher:

class Dispatcher{
  constructor(){
    this.events = {}
  }

  dispatch(eventName, data){
    const event = this.events[eventName]
    if(event){
      event.fire(data)
    }
  }

  //start listen event
  on(eventName, callback){
    let event = this.events[eventName]
    if(!event){
      event = new DispatcherEvent(eventName)
      this.events[eventName] = event
    }
    event.registerCallback(callback)
  }
  
  //stop listen event
  off(eventName, callback){
    const event = this.events[eventName]
    if(event){
      delete this.events[eventName]
    }
  }
}

DispatcherEvent:

class DispatcherEvent{
  constructor(eventName){
    this.eventName = eventName
    this.callbacks = []
  }

  registerCallback(callback){
    this.callbacks.push(callback)
  }

  fire(data){
    this.callbacks.forEach((callback=>{
      callback(data)
    }))
  }
}

Happy coding!

p/s: My code is missing handle some error exceptions

Solution 8 - Javascript

When calling the callback function, we could use it like below:

consumingFunction(callbackFunctionName)

Example:

// Callback function only know the action,
// but don't know what's the data.
function callbackFunction(unknown) {
  console.log(unknown);
}

// This is a consuming function.
function getInfo(thenCallback) {
  // When we define the function we only know the data but not
  // the action. The action will be deferred until excecuting.
  var info = 'I know now';
  if (typeof thenCallback === 'function') {
    thenCallback(info);    
  }
}

// Start.
getInfo(callbackFunction); // I know now

This is the Codepend with full example.

Solution 9 - Javascript

function LoadData(callback) 
{
    alert('the data have been loaded');
    callback(loadedData, currentObject);
}

Solution 10 - Javascript

     function login(email, password, callback) {
         //verify the user
         const users = [
          { email: "[email protected]", password: "123" },
          { email: "[email protected]", password: "xyz" }
         ];

         const user = users.find(
           (user) => user.email === email && user.password === password
         );
         callback(user);
       `enter code here`}

    function redirect(user) {
       if (user) {
          //user is successfully logged in
          console.log("user is successfully logged in ");
       } else {
         console.log("Incorrect credentials ");
       } 
    }

    
    login("[email protected]", "123", redirect);

I hope this example will help everyone who wants to know about the callback in JS

Solution 11 - Javascript

Try:

function LoadData (callback)
{
    // ... Process whatever data
    callback (loadedData, currentObject);
}

Functions are first class in JavaScript; you can just pass them around.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAmgad FahmiView Question on Stackoverflow
Solution 1 - JavascriptT.J. CrowderView Answer on Stackoverflow
Solution 2 - JavascriptDonald A Nummer JrView Answer on Stackoverflow
Solution 3 - JavascriptK. Kilian LindbergView Answer on Stackoverflow
Solution 4 - Javascriptarun bahalView Answer on Stackoverflow
Solution 5 - JavascriptEyad FarraView Answer on Stackoverflow
Solution 6 - JavascriptDan BrayView Answer on Stackoverflow
Solution 7 - JavascripthienView Answer on Stackoverflow
Solution 8 - JavascriptEric TanView Answer on Stackoverflow
Solution 9 - JavascriptThomas BoniniView Answer on Stackoverflow
Solution 10 - JavascriptMuhammad Atif AkramView Answer on Stackoverflow
Solution 11 - JavascriptK PrimeView Answer on Stackoverflow