Funções de Retorno (callback)

As funções de retorno ou funções de callback são funções passadas como argumentos dentro de outras funções a fim de serem utilizadas em um momento posterior. Esse tipo de prática normalmente é utilizado para executar uma rotina após uma execução assíncrona ter terminado, mas nada impede a utilização na programação síncrona.

Veja como essas funções são utilizadas:

//multiplica 2 números
function mult(x,y){ 
   return x * y;  
}

//Adiciona 2 números
function add(x,y){  
   return x + y;
}

//Usa a função para computar os valores
function calcular(x, y, computar){ 
   return computar(x,y);
}

let a = calcular(10, 5, add); //utiliza a função add como função de retorno
console.log(a); // loga no console: 15

let b = calcular(10, 5, mult); 
console.log(b); // loga no console: 50

Funções de retorno anônimas

Callbacks podem ser criadas sem estarem ligadas a uma função especifica. Você pode passar uma função anônima como um callback é necessário já que elas são simples e fáceis de criar.

Veja um exemplo de uma função anônima sendo usada como função de retorno:

let c = calcular(10, 5, function(x,y){ //Utiliza uma função anônima como Callback
    return x - y; //retorna a subtração de x menos y.
});

console.log(c); // exibe o valor 5 no console

O mesmo pode ser feito utilizando funções de flecha (funções arrow)

let d = calculate(10,5, (x,y) => {return x - y}); //Usando uma função arrow

console.log(d); // Exibe 5 no console

Exemplos de Métodos que utilizam as funções de Callback

Existem diversas funções JavaScriptque aceitam funções callback como argumento.

map()

O método map() chama uma função de retorno em cada elemento do vetor e então retorna um novo vetor com os resultados.

Veja como o método map() utiliza funções de callback:

let array = [1,2,3,4,5];

let novoArray = array.map(function(x){ //Utiliza uma função anônima de callback para calcular o quadrado de cada elemento
    return x * x;
});

console.log(newArray);
// exibe [1,4,9,16,25] no console

filter()

O método filter() remove elementos do vetor que não passam por um critério especifico que será definido na função callback passada.

Veja como o metodo filter() é utilizado para remover elementos de um vetor que não sejam pares:

let array = [1,2,3,4,5];

function isEven(x){ //Confere se o valor é par.
   return x % 2 == 0; 
}

let newArray = array.filter(isEven); //Utiliza a função como callback para saber se o valor e par

console.log(newArray);
// eixbe [2,4] no console.

Continuation Passing Style(CPS)

O Continuation Passing Style(CPS) é um estilo de programação utilizado para encadear funções de callback juntas. Nele metodos com funções de callback são chamadas dentro de outras funções de callback. Esse estilo também é caracterizado por essas funções como seu ultimo parametro passado. Veja o exemplo:

//Aqui vamos chamar a função passando o valor 10 com o primeiro parametro e
//uma função anonima como segundo parametro
funcaoCPS(10, function (x) { //callback 1
    console.log(x);//exibe 10
    var resultado1 = x * x; 
    console.log(resultado1)//exibe = 100

    //Esse é o segundo callback da função, fazendo uma operação similar a
    //primeira chamada, mas com uma função anonima um pouco diferente.
    funcaoCPS(resultado1, function (y) { //callback 2 chamada dentro do callback 1
        console.log(y);//exibe = 100
        var resultado2 = y + y; 
        console.log(resultado2);//exibe = 200
    });
});

Qual a vantagem do CPS?

A principal razão é que o CPS nos dá controle total sobre o fluxo de controle. Normalmente, o fluxo de controle é manipulado pela linguagem: as instruções são executadas uma após a outra, e nós podemos apenas pular usando o fluxo de controle interno como instruções if, loops, funções, exceções e instruções de retorno. No CPS, não temos instruções uma após a outra: em vez disso, cada “instrução” tem uma chamada de função explícita para a próxima. Isso significa que podemos fazer o que quisermos com ele, incluindo armazená-lo em uma variável e usá-lo várias vezes, ignorando a próxima instrução ou seguindo uma continuação diferente inteiramente.

O CPS também é útil para operações cooperativas de multithreading e non-blocking. A linguagem ainda pode ter um único encadeamento na perspectiva de instruções – executadas uma após a outra – e apenas alternar tarefas entre retornos de chamada. O Node.JS é um ótimo exemplo desse estilo de programação mais diretamente: o código que faz o IO com o Node é escrito no CPS.


Conclusão

Então essa foi uma breve introdução sobre funções de callback. Caso você tenha interesse em posts similares a este, por favor deixe sua dica nos comentários para que eu possa montar um tutorial sobre o assunto

Fonte:

https://developer.mozilla.org/en-US/docs/Glossary/Callback_function

Asynchronous Programming with Javascript

Deixe um comentário