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