Eduardo Figueiredo
Eduardo Figueiredo

Reputation: 141

Why to use callback functions when I can simply call them?

I was reading about callback functions here (also in an online course which I am participating) and now I am stuck. The reason is that I cannot understand Why do I need to use callback functions if I can simply call them. Exemples below:

1 - Using callback functions:

    function showArticle(id, callbackSuccess, callbackError){
        
        if (true){
            callbackSuccess("This is a callback function", "It is very utilized.");
        } else {
            callbackError("Error on data recovery.");
        }

    }

    var callbackSuccess = function(title, description){
        document.write("<h1>" + title + "</h1>");
        document.write("<hr>");
        document.write("<p>" + description + "</p>");
    }

    var callbackError = function(error){
        document.write("<p><b>Erro:</b>" + error + "</p>");
    }

    showArticle(1, callbackSuccess, callbackError);

2 - Here is my code not using callback functions and having the same results:

    function showArticle(id){
        
        if (true){
            callbackSuccess("This is a callback function", "It is very utilized.");
        } else {
            callbackError("Error on data recovery.");
        }

    }

    var callbackSuccess = function(title, description){
        document.write("<h1>" + title + "</h1>");
        document.write("<hr>");
        document.write("<p>" + description + "</p>");
    }

    var callbackError = function(error){
        document.write("<p><b>Erro:</b>" + error + "</p>");
    }

    showArticle(1);

Why should I use callback functions and not simply calling them in the example 2?

Upvotes: 5

Views: 2656

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1075587

You're right, there's no point to the callback functions in the example you've given, but that's not how callback functions are normally used.

Typically, callbacks are used:

  1. By iteration, mapping, or filtering functions that call your callback for every element in an array, list, or other container

  2. By functions that perform asynchronous work that call your callback when the work is successfully completed, fails, or both (depending on the style of the API you're calling)

  3. By functions that accept callbacks they'll call when or if something happens, such as a click event handler on a DOM element

...but there are other categories as well.

The filter function on arrays is an example of #1: It calls the callback for each entry in the array, using the return value of the callback to decide whether the entry should be in the new, filtered array it returns:

const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const odds = numbers.filter(num => {
    console.log(`callback called with ${num}`); // logs 10 times
    return num % 2;
});
console.log(odds); // [1, 3, 5, 7, 9]

The Promise methods then, catch, and finally are examples of #2. Let's assume we have a startSomethingAsynchronous function that returns a promise. Here's how the fulfillment and rejection handlers (callbacks) might be set up:

startSomethingAsynchronous()                // Starts an asynchronous process
.then(result => {                           // <−+
    // ...do something with the result...   //   +− This is a fulfillment handler
})                                          // <−+
.catch(error => {                           // <−+
    // ...report or handle error...         //   +− This is a rejection handler
});                                         // <−+

The fulfillment handler is called if the promise from startSomethingAsynchronous() is fulfilled (successfully completed). The rejection handler is called if that promise is rejected (fails), or if that promise is fulfilled but the promise returned by then rejects (for instance, because an error occurs in the fulfillment handler). (Chaining things like this is fairly common, but there are lots of other ways to use promises, this is just one example.)

The addEventListener function in the DOM is an example of #3:

document.querySelector("input[type=button]")
    .addEventListener("click", function() {
        console.log("Clicked!"); // logs as many times as you click the button
    });
<input type="button" value="Click Me">

Upvotes: 7

iwaduarte
iwaduarte

Reputation: 1698

The above answers are right. Mine is just a simplification of one of the reasons (async nature)

Note that NOT everything is sequential.

  • A call to a database could take 100ms or 200ms or 1s to return data.
  • Reading a file that you do not know the size it could take X seconds.

In cases where you do not know how long a operation will take you use the callback approach and that is a JavaScript feature.

Some languages block the flow (I will wait the call to the database) or create threads ( I will execute in another "process" those operations)

JS will go with Promises and callbacks.

Upvotes: 2

Laczk&#243; &#214;rs
Laczk&#243; &#214;rs

Reputation: 1118

JavaScript runs code sequentially in top-down order. However, there are some cases that code runs (or must run) after something else happens and also not sequentially. This is called asynchronous programming.

Callbacks make sure that a function is not going to run before a task is completed but will run right after the task has completed. It helps us develop asynchronous JavaScript code and keeps us safe from problems and errors.

In JavaScript, the way to create a callback function is to pass it as a parameter to another function, and then to call it back right after something has happened or some task is completed.

- freecodecamp.org

You can read more here.

Upvotes: 2

Related Questions