What is callback?

132

I see in many codes and even architectures the word callback, I see that it is in JavaScript functions.

  • But what is it?
  • How is it used?
  • Why?

I would like an example of actual usage.

    
asked by Rod 31.07.2014 в 00:14

4 answers

138

Callback is a function that is used as "callback". It is typically passed as an argument to another function and / or called when an event occurs, or when a piece of code receives a response that it was expecting.

This is very common in javascript side client and server (NodeJS) but not only. The callback function is often asynchronous in that it is called as a consequence of another code that is running in the background. The big advantage is that so the computer can process other processes while the response does not arrive and does not need to stop everything waiting for this response.

A classic example is an event handler that calls a function when the event happens:

function callback(e) {
    alert('Aconteceu um evento ' + e.type);
}
window.addEventListener('click', callback);

This callback will be called when you click on the window. Until this happens the processor will process other things that happen in the application.

Example: link

Another example is an ajax call, which makes a request to the server and runs the function when it receives the response.

This function is a callback function. In the example below ( link ) I called it minhaCallBack .

function minhaCallBack(returnhtml) {
    $("#result").html(returnhtml);
    $("#loadingimg").hide();
}

$(document).ready(function (e) {
        $.ajax({
            url: form_url,
            type: form_method,
            data: form_data,
            cache: false,
            success: minhaCallBack
        }); 
});

Another example ( link ) is an animation that calls the callback at the end of the animation to be complete:

function completa() {
    alert('Este alert está dentro da função "callback"');
}
$('div').animate({
    'height': '200px'
}, {
    duration: 2000,
    complete: completa
});

Another example still, to try to clarify more after it pops up one more question on the subject .

I'll make an analogy between synchronous code and asynchronous code. Imagining this situation:

Problem:

  

How to transform a string number, with decimal part too long that should be converted into dollars, and check if a given customer is entitled to discount.

Synchronous solution:

To solve this problem synchronously, we need to know the initial value and the value of the exchange before to start the calculation. This is not always the case, but for the example we will assume that we know the following:

var valorInicial = "1003,087293487";
var descontoCliente = "5%";
var cambio =  1.1158; // 1 EUR = 1.11580USD

So we can do the transformation in a simple way:

var valorInicialEmFormatoNumerico = Number(valorInicial.replace(',', '.'));
var valorComDescontoAplicado = valorInicialEmFormatoNumerico - (valorInicialEmFormatoNumerico * parseFloat(descontoCliente) / 100);
var valorEmDolares = valorComDescontoAplicado * cambio;
var totalComDuasCasasDecimais = valorEmDolares.toFixed(2);

So the result is obtained with synchronous steps, and gives 1063.28

Asynchronous solution:

Now imagine that we need to do the same thing, but we do not have all the information available, because the changes are constantly changing, we can not have the discount available to all possible customers, not even the initial price because we have to ask the our supplier first.

How to do it?

In this case we have to do the asynchronous thing, ie running part of the code, wait for answers, run another piece and wait for another answer, etc ...

We can say that when we ask something something to an outside service we probably make an ajax request. And now we need a tool to get the answer, that's where callbacks come into play.

When I send a question to an external service I have to tell you how it should contact me / inform me of the result. A common way is to send a function with the request so that it is run when the response arrives.

  

Send a function with the request so that it is run when the response arrives

If I send a function to a setTimeout, I tell setTimeout which code to run when the time has run out. This function can have the name we want, but its functionality, its type is callback :

var fazerAlgo = function(){ alert('O tempo chegou ao fim!'); }
setTimeout(fazerAlgo, 2000); // correr ao fim de 2 segundos

Returning to the account example:

To do the above calculation with asynchronous logic we have to chain things together and depend on functions that are called with wait times between them. So we have to chain everything, for example like this:

pedirPrecoAoFornecedor(numeroProduto, function(respostaDoFornecedor) {
  var valorInicialEmFormatoNumerico = Number(respostaDoFornecedor.replace(',', '.'));
  pedirInformacaoDesconto(numeroCliente, function(descontoCliente) {
    var valorComDescontoAplicado = valorInicialEmFormatoNumerico - (valorInicialEmFormatoNumerico * parseFloat(descontoCliente) / 100);
    pedirCambioDaHora('USD', function(valorDoDolar) {
      var valorEmDolares = valorComDescontoAplicado * valorDoDolar;
      var totalComDuasCasasDecimais = valorEmDolares.toFixed(2);

      // !! agora temos o resultado!! 
      alert(totalComDuasCasasDecimais + 'USD');

    })
  })
})

This chaining of functions is necessary because each callback will be called when the external service wants. For example, the pedirPrecoAoFornecedor function receives two arguments: the product number and a function. As I know that what I will receive is the price of the product I already put this as variable name, for easier reading. This function that passes the pedirPrecoAoFornecedor is therefore a callback, a mechanism for the external service to be able to return what I need.

    
31.07.2014 / 00:28
55

CallBack (or callback ) is a flow control mechanism that aims to benefit asynchronous processes.

The main idea is to release the application so that other actions are taken without it waiting for the return of synchronous processes, waiting for a remote response, or (in case the framework in> threading ) with high processing power if you opened a separate thread to wait for the response.

In a traditional mechanism, the synchronous request (and consequent waiting) for a resource would thus be in pseudocode:

Var B = A.SoliciteRecurso();
Print B.Nome;

Let's say operations within SoliciteRecurso() take a minute. in this case, your application will wait all the time for the answer.

Now an asynchronous operation via CallBack:

Objeto.AssinarRetornoDeSoliciteRecurso += ProcessarRetorno;
Var B = A.SoliciteRecursoAssincrono();

função ProcessarRetorno(Objeto B)
{
    Print B.Nome;
}

In this case, the application control is returned shortly after the SoliciteRecursoAssincrono() method. When, and if, the A object generates the event that triggers AssinarRetornoDeSoliciteRecurso , the ProcessarRetorno method is called.

Several modern technologies use this feature. For example, this snippet in AngularJS :

function directoryController($scope, $http) {
    'use strict';
    $scope.url = 'backend/services/dir.aspx?q=';

    $scope.search = function() {
        $http.post($scope.url + $scope.keywords).
            success(function(data, status) {
                $scope.status = status;
                $scope.data = data;
                $scope.listOfUsers = data;
            }).
            error(function(data, status) {
                $scope.data = data || "Request failed";
                $scope.status = status;
            });
    };

Basically says:

  • In method search , access this URL via method Post .
  • Successful event (event success ), proceed this way.
  • If an error has occurred (event error ), proceed in this other way.

The benefits brought by asynchronous calls are clear: You have a more responsive application with less processing power.

On the other hand, it introduces new paradigms that you need to treat in your code, such as asynchronous flow control (for example, 'only advance if you have received the successful return of the M method.' )

    
31.07.2014 в 17:11
24

When an event (click on a button, page load completed, mouse over any element, etc.) happens, the browser notifies all listeners, calling its calback functions .

window.addEventListener("load", function(){
    console.log("Eu sou uma função de callback, prazer!");
});

In the example above, we add an onload event listener in the window (that is, we require the browser to call our anonymous function - function(){...} - as soon as the page finishes loading in the user's computer memory) / p>

Basically, we can do many things with a callback function: swap text on page, hide elements, among many other uses.

    
31.07.2014 в 00:30
4
  

But what is it?

A callback function is that function that can be called by the method that receives it at any time.

In a pseudo language, it would look something like this:

funcao(Function funcaoCallback) {
    // funcao faz diversas coisas
    funcaoCallback.call(); // chama a função passada por parâmetro
}

This concept is commonly associated with the Javascript language due to the popularity of this language, since from its beginnings Javascript accepts the passing of methods as a parameter to a function. Other popular programming languages only came to have this kind of features many years later, as with Java.

  

How is it used?

There are different ways to use it in each language, and conceptually it can be used in countless ways.

Let's look at an example in Java. In Java 8 you can pass a method of any class to a method that accepts the Supplier parameter. Imagining that we have this method in a class called RetryMethod :

public void run(Supplier<T> callbackFunction) throws Exception {
    try {
        // código fazendo inúmeras coisas
        callbackFunction.get(); //chamada da função recebida por parâmetro
    } catch (Exception e) {
        log.warn("Command failed", e);
        return retry(function);
    }
}

And to pass the function to this method:

RetryMethod<Object> retryMethod = new RetryMethod<>();
retryMethod.run(() -> service.metodoChamadoPorCallback(qualquerParametro));

So, whatever the metodoChamadoPorCallback method does within the class with variable name service , the run method of the RetryMethod class has the full control of when to call it.

  

Why?

As I said earlier, the possibilities are endless.

In the example above, the code used can give control for the RetryMethod class of the metodoChamadoPorCallback method to be called different times in case of a Exception inside it, making several retries ). This class RetryMethod could receive any type of function in which the purpose is to repeat the call of the function passed to callback , regardless of what the function does.

    
02.07.2018 в 18:45