Uma função de retorno de chamada é uma função, em JavaScript. É passado para outra função como argumento, que é invocado dentro da função externa para concluir algum tipo de rotina ou ação.
Um ouvinte de evento também é uma função de retorno de chamada, um tipo especial (veja detalhes na parte inferior).
Exemplo de função de retorno de chamada:
saudação de função (msg) { console.log (msg); } função sayHello (nome, retorno de chamada) { const greet = 'Olá' + nome; retorno de chamada (cumprimentar); } sayOlá ('João', saudação);
Olá john
A função de retorno de chamada também pode ser transmitida como uma função anônima ou seta:
sayHello ('John', função (texto) {console.log (texto)}); sayHello ('John', (texto) => console.log (texto));
O exemplo acima é um retorno de chamada síncrono, pois é executado imediatamente.
Um retorno de chamada assíncrono:
const getData = função (retorno de chamada) { const data = {note: 'A mensagem é: Tic-tac-toe'}; setTimeout (() => { retorno de chamada (dados); } 3000) } retorno de chamada const = função (dados) { console.log (data.note) } getData (retorno de chamada);
A mensagem é: Tic-tac-toe
A função getData recebe um retorno de chamada que é executado após algum trabalho (nesse caso, o trabalho retorna após 3 segundos com um objeto).
Ouvintes de Eventos no Navegador:
Vamos pegar este exemplo de código usando HTML e JS:
O HTML:
Sempre que o elemento do botão é clicado, um pop-up com o botão "Login clicado!" vai aparecer. A ação de clique no botão produz um evento 'clique'. Por sua vez, executa a função de manipulador de clique que lida com o evento click - executa algum código em uma função. A função do manipulador é uma função de retorno de chamada.
Observe que esta função é um retorno de chamada. Além disso, a função é executada quando um evento específico ocorre. Este é um ouvinte de eventos.
Ouvintes de Eventos no NodeJS:
O módulo de eventos possui uma classe EventEmitter com recursos usando esse conceito de ouvinte de evento. Aqui está um exemplo:
const EventEmitter = require ('eventos'); emissor constante = novo EventEmitter (); emitter.addListener ('ev', function () { console.log ('ocorreu um evento!'); }); emitter.emit ('ev');
um evento ocorreu!
No código acima, a função anônima transmitida ao método addListener do emissor é um ouvinte de eventos e também uma função de retorno de chamada. O retorno de chamada é executado sempre que um evento 'ev' é emitido pelo emissor (usando o método de emissão).
A diferença é que uma função de retorno de chamada, como o nome diz, é uma função usada como retorno de chamada.
Como exemplo:
função connect ($ address, $ callback) { $ conectado = conectar0 (endereço $); if ($ conectado) { $ callback-> execute (); } } connect ("123.123.123.123:8080", function () { eco "Conectado com sucesso!"; });
De um modo geral, a função de retorno de chamada é algo que você passa no tempo de design (quando você escreve seu programa), e geralmente é um argumento e, em muitos casos, necessário. E, é claro, na maioria das vezes o retorno de chamada é implementado como uma função, não como classe.
Em outras palavras, um retorno de chamada é algo esperado pelo código do aplicativo ou módulo e será (na maioria dos casos) sempre executado.
O Event Listener é uma classe ou uma função que é chamada em tempo de execução (momento em que seu programa é realmente executado). Normalmente faz parte de um conceito maior chamado padrão Observador (ou Publicador / Assinante), em que alguns componentes de aplicativos se inscrevem em eventos e outros componentes emitem esses eventos (sem saber ou se importar com quem está inscrito). Daí outra diferença: um evento, quando despachado, pode ser tratado por nenhum, um ou vários ouvintes, e o módulo que o emite pode nem saber ou se importar com os ouvintes conectados.
Por outro lado, o módulo sempre sabe qual retorno de chamada espera e quando executá-lo. Essa lógica é codificada no módulo.
Conseqüentemente, os Listeners de Eventos permitem criar aplicativos muito mais frouxamente acoplados (o que é bom). Por outro lado, quando você está visualizando o código que emite o evento, geralmente é difícil dizer quais ouvintes serão chamados, sem inspecionar outras partes do código.
Considere um exemplo em Javascript:
// Uma implementação básica do Event Observer deixe ouvintes = {} função listen (evento, newListener) { // descartar ouvintes inválidos if ('function'! == typeof newListener) { Retorna } // configure um novo evento, se necessário if ('indefinido' === tipo de ouvintes [evento]) { listeners [evento] = nova matriz } // registra o ouvinte no evento listeners [event] .push (newListener) } função emitir (evento, dados) { if (Array.isArray (listeners [evento])) { listeners [event] .forEach (ouvinte => ouvinte (dados)) } } função assíncrona fetchApiData (terminal, retorno de chamada) { deixe request = new XMLHttpRequest () request.open ('GET', ponto final) resposta constante = aguardar request.send () if ('function' === typeof callback) { retorno de chamada (resposta) } emit ('api_response', resposta) }
Imagine que o código acima esteja empacotado como um módulo de terceiros e você o importe e use em seu aplicativo.
"FetchApiData" aceita um retorno de chamada e emite eventos. Isso permite que você o use de 2 maneiras diferentes.
Agora, se você deseja executar essa lógica de sucesso apenas em uma situação específica, transmite um retorno de chamada:
fetchApiData ( 'https://myawesomeapi.io', response => console.log ('Hooray! resposta recebida! Mas psssst!') )
Mas se existe alguma lógica que você sabe que sempre será executada para todo tipo de resposta, você pode registrar um ouvinte de evento e esquecer a necessidade de qualquer retorno de chamada:
listen ('api_response', response => silentlyLogResponse (response))
agora sempre que você chamar fetchApiData, ele chamará silentlyLogResponse (response) porque emite o evento automaticamente. Não há mais necessidade de retornar o retorno de chamada.
fetchApiData ('https://myawesomeapi.io') // chama silenciosamenteLogResponse
e você pode registrar quantos ouvintes quiser em um evento:
listen ('api_response', updateDOM) listen ('api_response', makeCoffee) listen ('api_response', playMusic) listen ('api_response', makeAmericaGreatAgain)
E todos serão executados sempre que um evento for emitido.
Pergunta: Qual é a diferença entre uma função de retorno de chamada e um ouvinte de evento?
A diferença é principalmente apenas caso de uso. Eles são essencialmente a mesma coisa exata. Cada uma é uma função ou procedimento executado após a conclusão de algum evento ou atividade.
Por exemplo, em C, existe uma função chamada qsort () que executa uma classificação rápida em uma matriz ou buffer e exige que ele passe um ponteiro para uma função - uma função de retorno de chamada. Essa função para todos os propósitos e finalidades pode ser considerada um manipulador de eventos onCompare (), pois essa função / ponteiro é chamada sempre que 2 itens no conjunto passados a ele precisarem ser comparados entre si.
Essencialmente, funções de retorno de chamada, manipuladores de eventos, ouvintes, publicador / assinante e Observable / Observer são nomes diferentes para o mesmo padrão de design com casos de uso ligeiramente diferentes. As funções de retorno de chamada geralmente são chamadas como tal quando alguém chama uma função e precisa passar a função de retorno de chamada para a primeira função que está sendo chamada. Geralmente é também por um período muito curto. Na situação em que um campo em uma classe / objeto está sendo definido, frequentemente isso é chamado de manipulador de eventos. No entanto, existem muitas situações, especialmente em Javascript no JQuery, em que se chama funções / métodos como setClick () e passa uma função como argumento. Isso ocorre por um período muito maior do que a execução de uma função. O mesmo acontece com Publicador / Assinante e Observável / Observador - Períodos mais longos. Ouvintes são essencialmente a mesma coisa que Manipuladores de Eventos, mas o termo é preferido em algumas linguagens como Java.