80 lines
4.9 KiB
Markdown
80 lines
4.9 KiB
Markdown
|
---
|
|||
|
title: Callback Functions
|
|||
|
localeTitle: Funções de retorno
|
|||
|
---
|
|||
|
Este artigo apresenta uma breve introdução ao conceito e uso de funções de retorno de chamada 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 eles da mesma maneira que trabalhamos com outros objetos, como atribuí-los a variáveis e passá-las como argumentos para outras funções. Isso é importante, porque é a última técnica que nos permite estender a funcionalidade em nossos aplicativos.
|
|||
|
|
|||
|
## Funções de retorno
|
|||
|
|
|||
|
Uma **função de retorno de chamada** é uma função que é passada _como um argumento_ para outra função, para ser "chamada de volta" mais tarde. 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 retorno de chamada é executada. É a combinação desses dois que nos permitem ampliar nossa funcionalidade.
|
|||
|
|
|||
|
Para ilustrar as chamadas de retorno, vamos começar com um exemplo simples:
|
|||
|
|
|||
|
```javascript
|
|||
|
function createQuote(quote, callback){
|
|||
|
var myQuote = "Like I always say, " + quote;
|
|||
|
callback(myQuote); // 2
|
|||
|
}
|
|||
|
|
|||
|
function logQuote(quote){
|
|||
|
console.log(quote);
|
|||
|
}
|
|||
|
|
|||
|
createQuote("eat your vegetables!", logQuote); // 1
|
|||
|
|
|||
|
// Result in console:
|
|||
|
// Like I always say, eat your vegetables!
|
|||
|
```
|
|||
|
|
|||
|
No exemplo acima, `createQuote` é a função de ordem mais alta, que aceita dois argumentos, sendo o segundo o retorno de chamada. A função `logQuote` está sendo usada para passar como nossa função de retorno de chamada. Quando executamos a função `createQuote` _(1)_ , observe que não estamos _anexando_ parênteses ao `logQuote` quando o passamos como um argumento. Isto é porque nós não queremos executar nossa função callback imediatamente, nós simplesmente queremos passar a definição da função para a função de ordem mais alta para que ela possa ser executada posteriormente.
|
|||
|
|
|||
|
Além disso, precisamos garantir que, se a função de retorno de chamada que esperamos receber argumentos, forneça esses argumentos ao executar o retorno de chamada _(2)_ . No exemplo acima, isso seria o `callback(myQuote);` declaração, uma vez que sabemos que o `logQuote` espera que uma citação seja passada.
|
|||
|
|
|||
|
Além disso, podemos passar funções anônimas como retornos de chamada. A chamada abaixo para `createQuote` teria o mesmo resultado que o exemplo acima:
|
|||
|
|
|||
|
```javascript
|
|||
|
createQuote("eat your vegetables!", function(quote){
|
|||
|
console.log(quote);
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
Aliás, você não _precisa_ usar a palavra "callback" como o nome do seu argumento, o Javascript só precisa saber que é o nome correto do argumento. Com base no exemplo acima, a função abaixo se comportará exatamente da mesma maneira.
|
|||
|
|
|||
|
```javascript
|
|||
|
function createQuote(quote, functionToCall) {
|
|||
|
var myQuote = "Like I always say, " + quote;
|
|||
|
functionToCall(myQuote);
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
## Por que usar retornos de chamada?
|
|||
|
|
|||
|
Na maioria das vezes, estamos criando programas e aplicativos que operam de maneira **síncrona** . Em outras palavras, algumas de nossas operações são iniciadas somente depois que as anteriores foram concluídas. Muitas vezes, quando solicitamos dados de outras fontes, como uma API externa, nem sempre sabemos _quando_ nossos dados serão exibidos. Nesses casos, queremos aguardar a resposta, mas nem sempre queremos que todo o nosso aplicativo seja interrompido enquanto nossos dados estão sendo buscados. Essas situações são onde as funções de retorno de chamada são úteis.
|
|||
|
|
|||
|
Vamos dar uma olhada em um exemplo que simula uma solicitação para um servidor:
|
|||
|
|
|||
|
```javascript
|
|||
|
function serverRequest(query, callback){
|
|||
|
setTimeout(function(){
|
|||
|
var response = query + "full!";
|
|||
|
callback(response);
|
|||
|
},5000);
|
|||
|
}
|
|||
|
|
|||
|
function getResults(results){
|
|||
|
console.log("Response from the server: " + results);
|
|||
|
}
|
|||
|
|
|||
|
serverRequest("The glass is half ", getResults);
|
|||
|
|
|||
|
// Result in console after 5 second delay:
|
|||
|
// Response from the server: The glass is half full!
|
|||
|
```
|
|||
|
|
|||
|
No exemplo acima, fazemos um pedido simulado para um servidor. Após 5 segundos, a resposta é modificada e, em seguida, nossa função de retorno de chamada `getResults` é 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 o `setTimeout` , estará usando as funções de retorno de chamada o tempo todo. O argumento de função anônimo passado na chamada de função `setTimeout` do exemplo acima também é um retorno de chamada! Portanto, o retorno de chamada original do exemplo é realmente executado por outro retorno de chamada. Tenha cuidado para não aninhar muitas chamadas de retorno, se você puder ajudá-lo, pois isso pode levar a algo chamado "callback hell"! Como o nome indica, não é uma alegria lidar com isso.
|