Artigo original: What is a Callback Function in JavaScript?
Este artigo fornece uma breve introdução ao conceito e uso de funções de callback na linguagem de programação JavaScript.
Funções são objetos
A primeira coisa que precisamos saber é que, em Javascript, as funções são objetos de primeira classe. Como tal, podemos trabalhar com elas da mesma maneira que trabalhamos com outros objetos. Podemos atribuí-los a variáveis e passá-los como argumentos para outras funções. Isso é importante, pois é a técnica que nos permite estender a funcionalidade de nossas aplicações.
Funções de callback
Uma função de callback é uma função que é passada como um argumento para outra função, para ser "chamada de volta" (em inglês, "called back") posteriormente. Uma função que aceita outras funções como argumentos é chamada de função de ordem superior, que contém a lógica para quando a função de callback é executada. É a combinação dessas duas que nos permite estender nossa funcionalidade.
Para ilustrar as funções de callback, vamos começar com um exemplo simples:
function criarFrase(frase, callback){
var minhaFrase = "Como eu sempre digo, " + frase;
callback(minhaFrase); // 2
}
function registrarFrase(frase){
console.log(frase);
}
criarFrase("coma verduras!", registrarFrase); // 1
// Resultado no console:
// Como eu sempre digo, coma verduras!
No exemplo acima, criarFrase
é a função de ordem superior, que aceita dois argumentos – sendo o segundo a função de callback. A função registrarFrase
é usada para passar nossa função de callback. Quando executamos a função criarFrase
(1), perceba que não estamos adicionando parênteses a registrarFrase
ao passá-la como argumento. Isso ocorre porque não queremos executar nossa função de callback imediatamente. Queremos apenas passar a definição da função para a função de ordem superior para que ela possa ser executada posteriormente.
Além disso, precisamos garantir que, se a função de callback que passamos espera argumentos, fornecemos esses argumentos ao executá-la (2). No exemplo acima, na instrução callback(minhaFrase);
, sabemos que registrarFrase
espera que uma frase seja passada para ela.
Também podemos passar uma função anônima como callback. A chamada abaixo a criarFrase
teria o mesmo resultado do exemplo acima:
criarFrase("coma verduras!", function(frase){
console.log(frase);
});
Aliás, você não precisa usar a palavra "callback" como o nome do seu argumento, o JavaScript só precisa saber qual é o nome correto do argumento. Com base no exemplo acima, a função abaixo se comportará exatamente da mesma maneira.
function criarFrase(fraee, funcaoASerChamada) {
var minhaFrase = "Como eu sempre digo, " + frade;
funcaoASerChamada(minhaFrase);
}
Por que usar funções de callback?
Na maioria das vezes, criamos programas e aplicações que operam de modo síncrono. Em outras palavras, algumas de nossas operações são iniciadas somente após a conclusão das anteriores. Muitas vezes, quando solicitamos dados de outras fontes, como uma API externa, nem sempre sabemos quando nossos dados serão fornecidos de volta. Nesses casos, queremos aguardar a resposta, mas nem sempre queremos que toda a nossa aplicação aguarde enquanto nossos dados são buscados. Essas situações são onde as funções de callback são mais úteis.
Vamos dar uma olhada em um exemplo que simula uma solicitação para um servidor:
function requisicaoAoServidor(consulta, callback){
setTimeout(function(){
var resposta = consulta + "cheio!";
callback(resposta);
},5000);
}
function obterResultados(resultados){
console.log("Resposta do servidor: " + resultados);
}
requisicaoAoServidor("O copo está meio ", obterResultados);
// Resultado no console após um atraso de 5 segundos:
// Resposta do servidor: O copo está meio cheio!
No exemplo acima, fazemos uma simulação de solicitação para um servidor. Após 5 segundos, a resposta é modificada e, em seguida, nossa função de callback obterResultados
é executada. Para ver isso em ação, você pode copiar/colar o código acima na ferramenta de desenvolvedor do seu navegador e executá-lo.
Além disso, se você já estiver familiarizado com setTimeout
, saiba que já vem usando funções de callback há algum tempo. A função anônima passada no exemplo acima da chamada da função setTimeout
também é uma função de callback! Assim, a função de callback original do exemplo é, de fato, executada por outra função de callback. Cuidado para não aninhar muitas callbacks. Evite isso, se possível, já que pode levar a algo chamado de "o inferno das callbacks" (em inglês, callback hell)! Como o próprio nome sugere, não é uma das melhores coisas com as quais desejaremos lidar.