Create a custom callback in JavaScript

Viewed 367308

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?

11 Answers

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`

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)

function LoadData(callback) 
{
    alert('the data have been loaded');
    callback(loadedData, currentObject);
}
     function login(email, password, callback) {
         //verify the user
         const users = [
          { email: "abc@gmail.com", password: "123" },
          { email: "xyz@gmail.com", 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("abc@gmail.com", "123", redirect);

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

Try:

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

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

Related