Como explicar retornos de chamada em inglês simples? Como eles são diferentes de chamar uma função de outra função, tendo algum contexto da função de chamada? Como o poder deles pode ser explicado a um programador iniciante?
function
callback
language-agnostic
terminology
Yahoo-Me
fonte
fonte
Respostas:
Freqüentemente, um aplicativo precisa executar diferentes funções com base em seu contexto / estado. Para isso, usamos uma variável na qual armazenamos as informações sobre a função a ser chamada. De acordo com sua necessidade, o aplicativo definirá essa variável com as informações sobre a função a ser chamada e chamará a função usando a mesma variável.
Em javascript, o exemplo está abaixo. Aqui usamos o argumento do método como uma variável em que armazenamos informações sobre a função.
fonte
function(arg)
) naprocessArray(arr,callback)
funçãoVou tentar manter esse morto simples. Um "retorno de chamada" é qualquer função chamada por outra função que aceita a primeira função como parâmetro. Na maioria das vezes, um "retorno de chamada" é uma função que é chamada quando algo acontece. Que algo pode ser chamado de "evento" na fala do programador.
Imagine este cenário: você está esperando um pacote em alguns dias. O pacote é um presente para o seu vizinho. Portanto, uma vez que você obtém o pacote, deseja que ele seja trazido para os vizinhos. Você está fora da cidade e deixa instruções para seu cônjuge.
Você poderia dizer a eles para pegar o pacote e levá-lo aos vizinhos. Se o seu cônjuge fosse tão estúpido quanto um computador, eles se sentariam à porta e esperariam o pacote até ele chegar (NÃO FAZENDO ALGO MAIS) e, depois que chegassem, o levariam aos vizinhos. Mas há uma maneira melhor. Diga ao seu cônjuge que, uma vez que receberem o pacote, eles deverão trazê-lo para os vizinhos. Então, eles podem seguir a vida normalmente até receberem o pacote.
Em nosso exemplo, o recebimento do pacote é o "evento" e o envio para os vizinhos é o "retorno de chamada". Seu cônjuge "executa" suas instruções para trazer o pacote somente quando o pacote chegar. Muito melhor!
Esse tipo de pensamento é óbvio na vida cotidiana, mas os computadores não têm o mesmo tipo de bom senso. Considere como os programadores normalmente gravam em um arquivo:
Aqui, esperamos que o arquivo seja aberto antes de escrever nele. Isso "bloqueia" o fluxo de execução e nosso programa não pode fazer nenhuma das outras coisas que possa precisar! E se pudéssemos fazer isso:
Acontece que fazemos isso com algumas linguagens e estruturas. É muito legal! Confira o Node.js para obter algumas práticas reais com esse tipo de pensamento.
fonte
open
funciona. É plausível queopen
possa bloquear internamente enquanto aguarda o sistema operacional fazer sua magia negra, na qual o retorno de chamada é executado. Não há diferença no resultado nesse caso.Em inglês simples, uma função de retorno de chamada é como um Trabalhador que "liga de volta" para seu Gerente quando ele conclui uma Tarefa .
É verdade que você está chamando uma função de outra função, mas a chave é que o retorno de chamada é tratado como um Objeto, para que você possa alterar qual Função chamar com base no estado do sistema (como o Padrão de Design da Estratégia).
O poder dos retornos de chamada pode ser facilmente visto em sites no estilo AJAX, que precisam extrair dados de um servidor. O download dos novos dados pode levar algum tempo. Sem retornos de chamada, toda a interface do usuário "congelaria" durante o download dos novos dados ou você precisaria atualizar a página inteira em vez de apenas parte dela. Com um retorno de chamada, você pode inserir uma imagem "now loading" e substituí-la pelos novos dados depois de carregados.
Algum código sem retorno de chamada:
Com retorno de chamada:
Aqui está um exemplo com um retorno de chamada, usando getJSON do jQuery :
Com fechamento:
Freqüentemente, o retorno de chamada precisa acessar
state
da função de chamada usando aclosure
, que é como o Trabalhador que precisa obter informações do Gerente antes que ele possa concluir sua Tarefa . Para criar oclosure
, você pode incorporar a função para que ela veja os dados no contexto de chamada:Uso:
Fecho
Finalmente, aqui está uma definição de
closure
de Douglas Crockford :As funções podem ser definidas dentro de outras funções. A função interna tem acesso aos vars e aos parâmetros da função externa. Se uma referência a uma função interna sobreviver (por exemplo, como uma função de retorno de chamada), os vars da função externa também sobreviverão.
Veja também:
fonte
Fico surpreso ao ver tantas pessoas inteligentes falhando em enfatizar a realidade que a palavra "retorno de chamada" passou a ser usada de duas maneiras inconsistentes.
Ambas as formas envolvem a personalização de uma função passando funcionalidade adicional (uma definição de função, anônima ou nomeada) para uma função existente. ie
Se a funcionalidade personalizada estiver simplesmente conectada ao bloco de código, você personalizou a função, assim.
Embora esse tipo de funcionalidade injetada seja freqüentemente chamado de "retorno de chamada", não há nada contingente. Um exemplo muito óbvio é o método forEach, no qual uma função personalizada é fornecida como um argumento a ser aplicado a cada elemento em uma matriz para modificar a matriz.
Mas isso é fundamentalmente distinto do uso de funções de "retorno de chamada" para programação assíncrona , como no AJAX ou node.js ou simplesmente na atribuição de funcionalidade a eventos de interação do usuário (como cliques do mouse). Nesse caso, a idéia é aguardar a ocorrência de um evento contingente antes de executar a funcionalidade customizada. Isso é óbvio no caso da interação do usuário, mas também é importante nos processos de E / S (entrada / saída) que podem levar tempo, como a leitura de arquivos do disco. É aqui que o termo "retorno de chamada" faz o sentido mais óbvio. Depois que um processo de E / S é iniciado (como solicitar que um arquivo seja lido do disco ou de um servidor para retornar dados de uma solicitação http), é assíncronaprograma não espera para terminar. Ele pode prosseguir com as tarefas agendadas a seguir e responder apenas com a funcionalidade personalizada após ter sido notificado de que o arquivo de leitura ou a solicitação http foi concluída (ou que falhou) e que os dados estão disponíveis para a funcionalidade personalizada. É como ligar para uma empresa por telefone e deixar seu número de "retorno de chamada", para que eles possam ligar quando alguém estiver disponível para entrar em contato com você. É melhor do que ficar na fila para quem sabe quanto tempo e não poder atender a outros assuntos.
O uso assíncrono envolve inerentemente alguns meios de escutar o evento desejado (por exemplo, a conclusão do processo de E / S) para que, quando ele ocorra (e somente quando ele ocorra), a funcionalidade "retorno de chamada" personalizada seja executada. No exemplo óbvio do AJAX, quando os dados realmente chegam do servidor, a função "retorno de chamada" é acionada para usar esses dados para modificar o DOM e, portanto, redesenhar a janela do navegador nessa extensão.
Para recapitular. Algumas pessoas usam a palavra "retorno de chamada" para se referir a qualquer tipo de funcionalidade personalizada que pode ser injetada em uma função existente como argumento. Mas, pelo menos para mim, o uso mais apropriado da palavra é onde a função "retorno de chamada" injetada é usada de forma assíncrona - para ser executada somente na ocorrência de um evento que está aguardando para ser notificado.
fonte
Array.prototype.forEach()
e a função passada como um argumento parasetTimeout()
, e eles são cavalos de cores diferentes, na medida em que você pensa sobre seu programa .Em termos não programadores, um retorno de chamada é um preenchimento em branco em um programa.
Um item comum em muitos formulários em papel é "Pessoa para ligar em caso de emergência". Há uma linha em branco lá. Você escreve o nome e o número de telefone de alguém. Se ocorrer uma emergência, essa pessoa será chamada.
Isso é fundamental. Você não altera o formulário (o código, geralmente o de outra pessoa). No entanto, você pode preencher as informações que faltam ( seu número).
Exemplo 1:
Os retornos de chamada são usados como métodos personalizados, possivelmente para adicionar / alterar o comportamento de um programa. Por exemplo, pegue um código C que executa uma função, mas não sabe como imprimir a saída. Tudo o que pode fazer é criar uma string. Quando tenta descobrir o que fazer com a string, vê uma linha em branco. Mas, o programador deu a você o espaço em branco para escrever sua chamada de retorno!
Neste exemplo, você não use um lápis para preencher um espaço em branco em uma folha de papel, você usa a função
set_print_callback(the_callback)
.set_print_callback
é o lápisthe_callback
é sua informação que você está preenchendo.Agora você preencheu esta linha em branco no programa. Sempre que precisar imprimir a saída, ela olhará para essa linha em branco e seguirá as instruções (ex: chamar a função que você coloca lá). Praticamente, isso permite a possibilidade de imprimir na tela, em um arquivo de log, em uma impressora, através de uma conexão de rede ou qualquer combinação deles. Você preencheu o espaço em branco com o que deseja fazer.
Exemplo 2:
Quando lhe dizem que precisa ligar para um número de emergência, você lê o que está escrito no formulário em papel e liga para o número que lê. Se essa linha estiver em branco, nada será feito.
A programação da GUI funciona da mesma maneira. Quando um botão é clicado, o programa precisa descobrir o que fazer a seguir. Ele vai e procura o retorno de chamada. Esse retorno de chamada acontece em um espaço em branco rotulado "Aqui está o que você faz quando o Botão1 é clicado"
A maioria dos IDEs preencherá automaticamente o espaço em branco para você (escreva o método básico) quando você solicitar (por exemplo
button1_clicked
). No entanto, esse espaço em branco pode ter qualquer método que você queira, por favor . Você pode chamar o métodorun_computations
oubutter_the_biscuits
desde que coloque o nome do retorno de chamada no espaço em branco apropriado. Você pode colocar "555-555-1212" no número de emergência em branco. Não faz muito sentido, mas é permitido.Nota final: a linha em branco que você está preenchendo com o retorno de chamada? Pode ser apagado e reescrito à vontade. (se você deve ou não é outra questão, mas isso faz parte do poder deles)
fonte
Sempre melhor começar com um exemplo :).
Vamos supor que você tenha dois módulos A e B.
Você deseja que o módulo A seja notificado quando ocorrer algum evento / condição no módulo B. No entanto, o módulo B não tem idéia do seu módulo A. Tudo o que sabe é um endereço para uma função específica (do módulo A) por meio de um ponteiro de função. fornecido pelo módulo A.
Portanto, tudo o que B precisa fazer agora é "retorno de chamada" no módulo A quando um evento / condição específico ocorre usando o ponteiro de função. A pode fazer um processamento adicional dentro da função de retorno de chamada.
*) Uma vantagem clara aqui é que você está abstraindo tudo sobre o módulo A do módulo B. O módulo B não precisa se preocupar com quem / o módulo A.
fonte
Johny, o programador, precisa de um grampeador, então ele vai até o departamento de suprimentos de escritório e pede um. Depois de preencher o formulário de solicitação, ele pode ficar parado ali e esperar o atendente ir procurar o grampeador no armazém (como uma chamada de função de bloqueio ) ou vá fazer outra coisa enquanto isso.
como isso geralmente leva tempo, johny coloca uma nota junto com o formulário de solicitação, solicitando que liguem para ele quando o grampeador estiver pronto para a coleta, portanto, enquanto isso, ele pode fazer outra coisa como cochilar em sua mesa.
fonte
Imagine que você precisa de uma função que retorne 10 ao quadrado para escrever uma função:
Mais tarde, você precisa de 9 ao quadrado para escrever outra função:
Eventualmente, você substituirá tudo isso por uma função genérica:
O mesmo pensamento se aplica aos retornos de chamada. Você tem uma função que faz alguma coisa e, quando concluída, chama doA:
Mais tarde, você deseja a mesma função exata para chamar doB, em vez disso, poderá duplicar toda a função:
Ou você pode passar uma função de retorno de chamada como uma variável e só precisa ter a função uma vez:
Então você só precisa chamar computação (doA) e computação (doB).
Além de simplificar o código, ele permite que o código assíncrono saiba que ele foi concluído ao chamar sua função arbitrária na conclusão, semelhante a quando você liga para alguém no telefone e deixa um número de retorno de chamada.
fonte
Você se sente mal e vai ao médico. Ele examina você e determina que você precisa de algum medicamento. Ele prescreve alguns remédios e chama a receita na sua farmácia local. Você vai para casa. Mais tarde, sua farmácia liga para informar que sua prescrição está pronta. Você vai buscá-lo.
fonte
Há dois pontos a serem explicados: um é como um retorno de chamada funciona (passando uma função que pode ser chamada sem nenhum conhecimento de seu contexto), o outro para o qual é usado (manipulando eventos de forma assíncrona).
A analogia de esperar a chegada de um pacote que tenha sido usado por outras respostas é boa para explicar as duas coisas. Em um programa de computador, você diria ao computador para esperar uma parcela. Normalmente, ele ficava ali sentado e aguardava (e não fazia mais nada) até que o pacote chegasse, possivelmente indefinidamente, se nunca chegar. Para os humanos, isso parece bobagem, mas sem outras medidas, isso é totalmente natural para um computador.
Agora a chamada seria a campainha na sua porta da frente. Você fornece ao serviço de encomendas uma maneira de notificá-lo da chegada da encomenda sem que eles precisem saber onde (mesmo se) você está na casa ou como a campainha funciona. (Por exemplo, alguns "sinos" realmente enviam uma ligação). Como você forneceu uma "função de retorno de chamada" que pode ser "chamada" a qualquer momento, fora do contexto, agora você pode parar de sentar na varanda da frente e "lidar com o evento "(de chegada de encomendas) sempre que for a hora.
fonte
Imagine que uma amiga está saindo de sua casa e você diz a ela "Me ligue quando chegar em casa para que eu saiba que você chegou em segurança"; isso é (literalmente) uma ligação de volta . É isso que é uma função de retorno de chamada, independentemente do idioma. Você deseja que algum procedimento repasse o controle para você quando concluir alguma tarefa, portanto, você atribui a ele uma função para chamá-lo.
Em Python, por exemplo,
grabDBValue
pode ser gravado para pegar apenas um valor de um banco de dados e permitir que você especifique o que realmente fazer com o valor, para que ele aceite uma função. Você não sabe quando ou segrabDBValue
retornará, mas se / quando ocorrer, você sabe o que deseja que faça. Aqui, passo uma função anônima (ou lambda ) que envia o valor para uma janela da GUI. Eu poderia facilmente mudar o comportamento do programa fazendo o seguinte:Os retornos de chamada funcionam bem em idiomas onde as funções são valores de primeira classe , assim como os números inteiros usuais, cadeias de caracteres, booleanos, etc. em Java, o chamador solicitará uma classe estática de um determinado tipo com um determinado nome de método, pois não há funções ("métodos", realmente) fora das classes; e na maioria das outras linguagens dinâmicas, você pode simplesmente passar uma função com sintaxe simples.
Protip:
Em idiomas com escopo lexical (como Scheme ou Perl), você pode fazer um truque como este:
$val
nesse caso, será6
porque o retorno de chamada tem acesso às variáveis declaradas no ambiente lexical em que foi definido. O escopo lexical e as chamadas de retorno anônimas são uma combinação poderosa que requer mais estudos para o programador iniciante.fonte
Você tem algum código que deseja executar. Normalmente, quando você o chama, espera que ele termine antes de continuar (o que pode fazer com que seu aplicativo fique cinza / produza um tempo de rotação para um cursor).
Um método alternativo é executar esse código em paralelo e continuar com seu próprio trabalho. Mas e se o seu código original precisar fazer coisas diferentes, dependendo da resposta do código que chamou? Bem, nesse caso, você pode passar o nome / local do código que deseja chamar quando terminar. Este é um "retorno de chamada".
Código normal: Peça Informações-> Informações do Processo-> Lide com os resultados do Processamento-> Continue fazendo outras coisas.
Com retornos de chamada: Solicite informações-> Informações do processo-> Continue fazendo outras coisas. E em algum momento posterior-> Lide com os resultados do processamento.
fonte
Sem retorno de chamada nem outros recursos especiais de programação (como threading e outros), um programa é exatamente uma sequência de instruções executadas seqüencialmente uma após a outra , e mesmo com um tipo de "comportamento dinâmico" determinado por determinadas condições, todos os cenários possíveis deve ser previamente programado .
Portanto, se precisarmos fornecer um comportamento dinâmico real a um programa, podemos usar o retorno de chamada. Com o retorno de chamada, você pode instruir por parâmetros, um programa para chamar outro programa, fornecendo alguns parâmetros definidos anteriormente e esperar alguns resultados ( esta é a assinatura do contrato ou da operação ), para que esses resultados possam ser produzidos / processados por um programa de terceiros que não foi não era conhecido anteriormente.
Essa técnica é a base do polimorfismo aplicado a programas, funções, objetos e todas as outras unidades de código executadas por computadores.
O mundo humano usado como exemplo para retorno de chamada é bem explicado quando você está fazendo algum trabalho, vamos supor que você seja um pintor ( aqui você é o programa principal, que pinta ) e, às vezes, ligue para o seu cliente para pedir que ele aprove o resultado do seu trabalho , ele decide se a imagem é boa ( seu cliente é o programa de terceiros ).
No exemplo acima, você é um pintor e "delega" a outros o trabalho para aprovar o resultado, a imagem é o parâmetro e cada novo cliente (a "função" chamada de retorno) altera o resultado do seu trabalho, decidindo o que ele deseja sobre a imagem ( a decisão tomada pelos clientes é o resultado retornado da "função de retorno de chamada" ).
Espero que esta explicação possa ser útil.
fonte
Vamos fingir que você deveria me dar uma tarefa potencialmente demorada: obter os nomes das cinco primeiras pessoas únicas que você se deparar. Isso pode levar dias se eu estiver em uma área escassamente povoada. Você não está realmente interessado em ficar sentado em suas mãos enquanto eu corro por aí, então você diz: "Quando tiver a lista, ligue para meu celular e leia de novo para mim. Aqui está o número".
Você me forneceu uma referência de retorno de chamada - uma função que devo executar para entregar mais processamento.
Em JavaScript, pode ser algo como isto:
Provavelmente isso poderia ser melhorado de várias maneiras. Por exemplo, você pode fornecer um segundo retorno de chamada: se demorar mais de uma hora, ligue para o telefone vermelho e diga à pessoa que responde que você atingiu o tempo limite.
fonte
Os retornos de chamada são descritos com mais facilidade em termos de sistema telefônico. Uma chamada de função é análoga a ligar para alguém no telefone, fazer uma pergunta, obter uma resposta e desligar; adicionar um retorno de chamada altera a analogia para que, depois de fazer uma pergunta, você também forneça seu nome e número para que ela possa ligar de volta com a resposta. - Paul Jakubik, "Implementações de retorno de chamada em C ++"
fonte
Um retorno de chamada é uma função que será chamada por uma segunda função. Esta segunda função não sabe de antemão qual função chamará. Portanto, a identidade da função de retorno de chamada é armazenada em algum lugar ou transmitida para a segunda função como parâmetro. Essa "identidade", dependendo da linguagem de programação, pode ser o endereço do retorno de chamada ou algum outro tipo de ponteiro, ou pode ser o nome da função. O principal é o mesmo, armazenamos ou passamos algumas informações que identificam inequivocamente a função.
Quando chegar a hora, a segunda função pode chamar o retorno de chamada, fornecendo parâmetros dependendo das circunstâncias naquele momento. Pode até escolher o retorno de chamada entre um conjunto de possíveis retornos de chamada. A linguagem de programação deve fornecer algum tipo de sintaxe para permitir que a segunda função chame o retorno de chamada, conhecendo sua "identidade".
Esse mecanismo tem muitos usos possíveis. Com os retornos de chamada, o designer de uma função pode permitir que ela seja personalizada fazendo com que ela chame os retornos de chamada fornecidos. Por exemplo, uma função de classificação pode usar um retorno de chamada como parâmetro, e esse retorno de chamada pode ser uma função para comparar dois elementos para decidir qual deles vem primeiro.
A propósito, dependendo da linguagem de programação, a palavra "função" na discussão acima pode ser substituída por "bloco", "encerramento", "lambda" etc.
fonte
Normalmente enviamos variáveis para funções. Suponha que você tenha uma tarefa em que a variável precisa ser processada antes de ser fornecida como argumento - você pode usar o retorno de chamada.
function1(var1, var2)
é o caminho usual.E se eu quiser
var2
ser processado e depois enviado como argumento?function1(var1, function2(var2))
Este é um tipo de retorno de chamada - onde
function2
executa algum código e retorna uma variável de volta à função inicial.fonte
Uma explicação metafórica:
Tenho uma encomenda que quero entregar a um amigo e também quero saber quando meu amigo a recebe.
Então, levo o pacote para os correios e peço que entreguem. Se eu quiser saber quando meu amigo recebe o pacote, tenho duas opções:
(a) Posso esperar nos correios até que seja entregue.
(b) Receberei um email quando ele for entregue.
A opção (b) é análoga a um retorno de chamada.
fonte
Para ensinar retornos de chamada, você deve ensinar o ponteiro primeiro. Depois que os alunos entenderem a idéia de apontar para uma variável, a idéia de retornos de chamada ficará mais fácil. Supondo que você esteja usando C / C ++, essas etapas podem ser seguidas.
Pode haver muito mais coisas. Envolva os alunos e eles descobrirão. Espero que isto ajude.
fonte
Em inglês simples, um retorno de chamada é uma promessa. Joe, Jane, David e Samantha compartilham uma carona para trabalhar. Joe está dirigindo hoje. Jane, David e Samantha têm algumas opções:
Opção 1: É mais como um exemplo de pesquisa em que Jane ficaria presa em um "loop", verificando se Joe estava do lado de fora. Jane não pode fazer mais nada nesse meio tempo.
Opção 2: este é o exemplo de retorno de chamada. Jane diz a Joe para tocar a campainha quando ele está do lado de fora. Ela lhe dá uma "função" para tocar a campainha da porta. Joe não precisa saber como a campainha da porta funciona ou onde ela está, ele só precisa chamar essa função, ou seja, tocar a campainha da porta quando estiver lá.
Os retornos de chamada são direcionados por "eventos". Neste exemplo, o "evento" é a chegada de Joe. No Ajax, por exemplo, os eventos podem ser "sucesso" ou "falha" da solicitação assíncrona e cada um pode ter o mesmo ou diferentes retornos de chamada.
Em termos de aplicativos JavaScript e retornos de chamada. Também precisamos entender "fechamentos" e o contexto do aplicativo. O que "isso" se refere pode facilmente confundir os desenvolvedores de JavaScript. Neste exemplo, dentro do método / retorno de chamada "ring_the_door_bell ()" de cada pessoa, pode haver outros métodos que cada pessoa precisa executar com base na rotina matinal ex. "desligue a televisão()". Queremos que "this" se refira ao objeto "Jane" ou ao objeto "David", para que cada um possa configurar o que mais precisar antes de Joe buscá-los. É aqui que a configuração do retorno de chamada com Joe exige a paródia do método, para que "this" se refira ao objeto correto.
Espero que ajude!
fonte
Um retorno de chamada é um envelope carimbado auto-endereçado. Quando você chama uma função, é como enviar uma carta. Se você deseja que essa função chame outra função, forneça essas informações na forma de uma referência ou endereço.
fonte
Eu acho que é uma tarefa bastante fácil de explicar.
No primeiro retorno de chamada, são apenas funções comuns.
E, além disso, chamamos essa função (vamos chamá-la de A) de dentro de outra função (vamos chamá-la de B).
A mágica disso é que eu decido qual função deve ser chamada pela função de fora de B.
No momento em que escrevo a função BI, não sei qual função de retorno de chamada deve ser chamada. No momento em que chamo a função BI, também digo a essa função para chamar a função A. Isso é tudo.
fonte
O que é uma função de retorno de chamada?
A resposta simples para essa primeira pergunta é que uma função de retorno de chamada é uma função chamada por meio de um ponteiro de função. Se você passar o ponteiro (endereço) de uma função como argumento para outro, quando esse ponteiro é usado para chamar a função, ele aponta para ele e diz que é feita uma chamada de retorno.
É difícil rastrear a função de retorno de chamada, mas às vezes é muito útil. Especialmente quando você está projetando bibliotecas. A função de retorno de chamada é como pedir ao usuário que lhe forneça um nome de função e você a chamará sob determinada condição.
Por exemplo, você escreve um cronômetro de retorno de chamada. Permite especificar a duração e qual função chamar, e a função será retornada de acordo. “Execute myfunction () a cada 10 segundos por 5 vezes”
Ou você pode criar um diretório de funções, passando uma lista do nome da função e solicitar à biblioteca que retorne a chamada adequadamente. "Sucesso de retorno de chamada () se for bem-sucedido, falha de retorno de chamada () se falhou."
Vamos ver um exemplo simples de ponteiro de função
Como passar o argumento para a função de retorno de chamada?
Observado que o ponteiro de função para implementar retorno de chamada recebe nulo *, o que indica que ele pode receber qualquer tipo de variável, incluindo estrutura. Portanto, você pode passar vários argumentos por estrutura.
fonte
Um retorno de chamada é um método que está programado para ser executado quando uma condição for atendida.
Um exemplo do "mundo real" é uma loja de videogame local. Você está esperando o Half-Life 3. Em vez de ir à loja todos os dias para ver se está, você registra seu email em uma lista para ser notificado quando o jogo estiver disponível. O email se torna seu "retorno de chamada" e a condição a ser atendida é a disponibilidade do jogo.
Um exemplo de "programadores" é uma página da web em que você deseja executar uma ação quando um botão é clicado. Você registra um método de retorno de chamada para um botão e continua executando outras tarefas. Quando / se o usuário clicar no botão, o navegador examinará a lista de retornos de chamada para esse evento e chamará seu método.
Um retorno de chamada é uma maneira de manipular eventos de forma assíncrona. Você nunca pode saber quando o retorno de chamada será executado ou se será executado. A vantagem é que ele libera seu programa e ciclos de CPU para executar outras tarefas enquanto aguarda a resposta.
fonte
Puro e simples: um retorno de chamada é uma função que você atribui a outra função, para que possa chamá- lo.
Geralmente é chamado quando alguma operação é concluída. Como você cria o retorno de chamada antes de entregá-lo à outra função, é possível inicializá-lo com informações de contexto do site de chamada. É por isso que é chamada de chamada * back * - a primeira função chama de volta ao contexto de onde foi chamada.
fonte
“Na programação de computadores, um retorno de chamada é uma referência ao código executável, ou um pedaço de código executável, que é passado como argumento para outro código. Isso permite que uma camada de software de nível inferior chame uma sub-rotina (ou função) definida em uma camada de nível superior. ” - Wikipedia
Retorno de chamada em C usando o ponteiro de função
Em C, o retorno de chamada é implementado usando o Ponteiro de Função. Ponteiro de função - como o nome sugere, é um ponteiro para uma função.
Por exemplo, int (* ptrFunc) ();
Aqui, ptrFunc é um ponteiro para uma função que não aceita argumentos e retorna um número inteiro. NÃO esqueça de colocar parênteses, caso contrário, o compilador assumirá que ptrFunc é um nome de função normal, que não aceita nada e retorna um ponteiro para um número inteiro.
Aqui está um código para demonstrar o ponteiro da função.
Agora vamos tentar entender o conceito de retorno de chamada em C usando o ponteiro de função.
O programa completo possui três arquivos: callback.c, reg_callback.he reg_callback.c.
Se rodarmos este programa, a saída será
Este é um programa que demonstra a função de retorno de chamada dentro de register_callback dentro de my_callback de volta no programa principal
A função de camada superior chama uma função de camada inferior como uma chamada normal e o mecanismo de retorno de chamada permite que a função de camada inferior chame a função de camada superior através de um ponteiro para uma função de retorno de chamada.
Retorno de chamada em Java usando a interface
Java não possui o conceito de ponteiro de função. Implementa o mecanismo de retorno de chamada através do seu mecanismo de interface. Aqui, em vez de um ponteiro de função, declaramos uma interface com um método que será chamado quando o destinatário concluir sua tarefa.
Deixe-me demonstrá-lo através de um exemplo:
A interface de retorno de chamada
O chamador ou a classe de nível superior
A função Callee ou a camada inferior
Retorno de Chamada Usando o Padrão EventListener
Esse padrão é usado para notificar de 0 a n números de Observadores / Ouvintes que uma tarefa específica foi concluída
A diferença entre o mecanismo de retorno de chamada e o mecanismo EventListener / Observer é que, no retorno de chamada, o destinatário notifica o chamador único, enquanto no Eventlisener / Observer, o destinatário pode notificar qualquer pessoa interessada nesse evento (a notificação pode ir para outras partes do aplicativo que não acionou a tarefa)
Deixe-me explicar através de um exemplo.
A interface do evento
Widget de classe
Botão de classe
Caixa de seleção Classe
Classe de atividade
pacote com.som_itsolutions.training.java.exampleeventlistener;
Outra classe
Classe principal
Como você pode ver no código acima, temos uma interface chamada events que basicamente lista todos os eventos que podem acontecer para nosso aplicativo. A classe Widget é a classe base de todos os componentes da interface do usuário, como botão e caixa de seleção. Esses componentes da interface do usuário são os objetos que realmente recebem os eventos do código da estrutura. A classe Widget implementa a interface Events e também possui duas interfaces aninhadas, a saber, OnClickEventListener e OnLongClickEventListener
Essas duas interfaces são responsáveis por ouvir os eventos que podem ocorrer nos componentes da interface do usuário derivados do Widget, como Botão ou Caixa de seleção. Portanto, se compararmos este exemplo com o exemplo anterior de retorno de chamada usando a interface Java, essas duas interfaces funcionarão como a interface de retorno de chamada. Portanto, o código de nível superior (Atividade aqui) implementa essas duas interfaces. E sempre que um evento ocorrer em um widget, o código de nível superior (ou o método dessas interfaces implementadas no código de nível superior, que é aqui Atividade) será chamado.
Agora, deixe-me discutir a diferença básica entre o padrão de retorno de chamada e ouvinte de evento. Como mencionamos, usando o retorno de chamada, o Callee pode notificar apenas um único chamador. Porém, no caso do padrão EventListener, qualquer outra parte ou classe do Aplicativo pode se registrar para os eventos que podem ocorrer no Botão ou na Caixa de Seleção. O exemplo desse tipo de classe é o OtherClass. Se você vir o código da OtherClass, descobrirá que ele se registrou como ouvinte do ClickEvent que pode ocorrer no botão definido na Atividade. Parte interessante é que, além da Atividade (o chamador), essa OtherClass também será notificada sempre que o evento click ocorrer no botão.
fonte
Os retornos de chamada permitem que você insira seu próprio código em outro bloco de código a ser executado em outro momento, que modifica ou adiciona ao comportamento desse outro bloco de código para atender às suas necessidades. Você ganha flexibilidade e capacidade de personalização enquanto pode ter um código mais sustentável.
Menos código rígido = mais fácil de manter e alterar = menos tempo = mais valor comercial = grandiosidade.
Por exemplo, em javascript, usando Underscore.js, você pode encontrar todos os elementos pares em uma matriz como esta:
Exemplo cortesia de Underscore.js: http://documentcloud.github.com/underscore/#filter
fonte
[editado] quando temos duas funções, digamos functionA e functionB , se functionA depende da funçãoB .
então chamamos functionB como uma função de retorno de chamada . isso é amplamente usado no framework Spring.
fonte
Pense em um método como dar uma tarefa a um colega de trabalho. Uma tarefa simples pode ser a seguinte:
Seu colega de trabalho faz as contas diligentemente e fornece o seguinte resultado:
Mas seu colega de trabalho tem um problema, ele nem sempre entende as notações, como
^
, mas ele as entende pela descrição. Tais comoexponent
. Toda vez que ele encontra um desses, você recebe de volta o seguinte:Isso exige que você reescreva todo o conjunto de instruções novamente depois de explicar o que o personagem significa para o seu colega de trabalho, e ele nem sempre se lembra entre as perguntas. E ele também tem dificuldade em se lembrar das suas dicas, como é o caso de me perguntar. Ele sempre segue suas instruções escritas da melhor maneira possível.
Você pensa em uma solução, basta adicionar o seguinte a todas as suas instruções:
Agora, sempre que ele tem um problema, ele liga e pergunta, em vez de dar uma resposta ruim e reiniciar o processo.
fonte
Isso em termos de download de uma página da web:
Seu programa é executado em um telefone celular e está solicitando a página da web http://www.google.com . Se você escrever seu programa de forma síncrona, a função que você escreve para baixar os dados estará em execução contínua até que todos os dados sejam baixados. Isso significa que sua interface do usuário não será atualizada e basicamente parecerá congelada. Se você escreve seu programa usando retornos de chamada, solicita os dados e diz "execute esta função quando terminar". Isso permite que a interface do usuário ainda permita a interação do usuário durante o download do arquivo. Após o download da página, sua função de resultado (retorno de chamada) é chamada e você pode manipular os dados.
Basicamente, ele permite que você solicite algo e continue executando enquanto aguarda o resultado. Depois que o resultado voltar para você por meio de uma função de retorno de chamada, você poderá retomar a operação de onde parou.
fonte