O que é uma função de callback?
o que é uma função de callback?
20 answers
Desenvolvedores são muitas vezes confundidos com o que é um callback por causa do nome da coisa maldita.
Uma função de callback é uma função que é:
- acessível por outra função, e
- é invocado após a primeira função se esta primeira função completar
Uma boa maneira de imaginar como uma função de callback funciona é que é uma função que é "chamada na parte de trás" da função em que é passada.
Talvez um nome melhor. seria uma função "chamada após" .Esta construção é muito útil para um comportamento assíncrono onde queremos que uma actividade ocorra sempre que um evento anterior termine.
Pseudocode:
// A function which accepts another function as an argument
// (and will automatically invoke that function when it completes - note that there is no explicit call to callbackFunction)
funct printANumber(int number, funct callbackFunction) {
printout("The number you provided is: " + number);
}
// a function which we will use in a driver function as a callback function
funct printFinishMessage() {
printout("I have finished printing numbers.");
}
// Driver method
funct event() {
printANumber(6, printFinishMessage);
}
Resultado se ligou para o evento():
The number you provided is: 6
I have finished printing numbers.
A ordem da saída aqui é importante. Uma vez que as funções de callback são chamadas depois, "eu terminei os números de impressão" é impresso em último lugar, não em primeiro lugar.
Os Callbacks são chamados de vencidos. ao seu uso com linguagens pontiagudas. Se não usares um desses, não trabalhes por causa do nome "callback". Basta entender que é apenas um nome para descrever um método que é fornecido como um argumento para outro método, tal que quando o método pai é chamado (qualquer condição, como um botão, um timer tick etc) e seu corpo método completa, a função de callback é então invocado.Algumas linguagens suportam construções onde são suportados vários argumentos da função de callback, e são chamados com base em como a função-mãe completa (ou seja, um callback é chamado no caso de que a função-mãe completa com sucesso, outro é chamado no caso de que a função-mãe lança um erro específico, etc).
Definição Opaca
Uma função de callback é uma função que você fornece a outro pedaço de código, permitindo que ele seja chamado por esse código.
Exemplo inventado
Porque queres fazer isto? Digamos que há um serviço que precisa de invocar. Se o serviço regressar imediatamente, apenas:- chama-lhe
- espera pelo resultado
- Continue assim que o resultado chegar
Por exemplo, suponha que o serviço era o factorial
funcao. Quando você quer o valor de 5!
, Você invocaria factorial(5)
, e os seguintes passos ocorreriam:
A sua localização de execução actual é gravada (na pilha, mas isso não é importante)
Execução é entregue a
factorial
Quando
factorial
completa, coloca o resultado em algum lugar onde você pode chegar a eleA execução volta para onde estava.[1]
Mantenha o seu design e execute o seu programa à noite quando você está dormindo, para que você não esteja olhando para o ecrã metade do tempo
Projecte o seu programa para fazer outras coisas enquanto
factorial
está a fazer a sua coisa
Concepção de ponta a ponta
A fim de explorar um padrão de callback, o que você quer é ser capaz de chamar factorial
da seguinte forma:
factorial(really_big_number, what_to_do_with_the_result)
O segundo parâmetro, what_to_do_with_the_result
, é uma função que você envia para factorial
, na esperança de que factorial
o Chame sobre o seu resultado antes de regressar.
Sim, isso significa que factorial
precisa ter sido escrito para apoiar callbacks.
factorial
precisa ser escrito para permitir que você passe seus parâmetros para dentro, e ele vai apenas entregá-los para o seu callback quando ele invoca. Pode parecer assim:
factorial (number, callback, params)
{
result = number! // i can make up operators in my pseudocode
callback (result, params)
}
Agora que factorial
permite este padrão, a sua chamada pode parecer assim:
logIt (number, logger)
{
logger.log(number)
}
E a sua chamada para factorial
seria
factorial(42, logIt, logger)
E se quiseres devolver alguma coisa de ... Não podes, porque ... não está a prestar atenção.
Porque é que não podes devolver o que devolves?
Tornando-o não bloqueador
Uma vez que a execução deve ser entregue ao callback quando estiver terminado, não deve devolver nada ao ouvinte. E idealmente, ele de alguma forma lançaria seu trabalho em outra thread / process / machine e retornaria imediatamente para que você pudesse continuar, talvez algo assim:factorial(param_1, param_2, ...)
{
new factorial_worker_task(param_1, param_2, ...);
return;
}
Isto agora é um assíncrono. call", significa que quando você ligar, ele retorna imediatamente, mas ainda não fez o seu trabalho. Então você precisa de mecanismos para verificá-lo, e para obter o seu resultado quando terminar, e seu programa ficou mais complexo no processo.
A propósito, usando este padrão, o {[28] } pode lançar a sua chamada de volta assíncronamente e regressar imediatamente.
Então, o que fazes?
A resposta é manter-se dentro do padrão de callback. Quando quiseres. escrever
a = f()
g(a)
E {[29] } deve ser chamado assíncronamente, em vez disso escreverás
f(g)
Onde g
é passado como um callback.
isso muda fundamentalmente a topologia de fluxo de seu programa, e leva algum tempo para se acostumar.
A sua linguagem de programação pode ajudá-lo muito, dando-lhe uma forma de criar funções em tempo real. No código imediatamente acima, a funçãog
pode ser tão pequena quanto print (2*a+1)
. Se a sua língua exigir que defina isso como uma função separada, com um nome e assinatura totalmente desnecessários, então sua vida vai ficar desagradável se você usar este padrão muito.
Se, por outro lado, a sua linguagem lhe permite criar lambdas, então está em muito melhor forma. Você vai acabar escrevendo algo como [[39]]
f( func(a) { print(2*a+1); })
O que é muito melhor.
Como Passar a chamada de volta
Como é que Passarias a função de callback parafactorial
? Bem, podes fazê - lo num número de formas.
Se a função chamada estiver rodando no mesmo processo, você pode passar um ponteiro de função
Ou talvez você queira manter um dicionário de
fn name --> fn ptr
em seu programa, caso em que você poderia passar o nomeTalvez a sua linguagem lhe permita definir a função no lugar, possível como um lambda! Internamente está criando algum tipo de objeto e passando um ponteiro, mas você não tem que se preocupar com que.
Talvez a função que você está chamando esteja rodando em uma máquina totalmente separada, e você está chamando-a usando um protocolo de rede como HTTP. Você poderia expor sua chamada de volta como uma função chamada HTTP, e passar a sua URL.
A página de retorno da Wikipédia explica muito bem.
citação da página do Wikipédia:
Na programação de computadores, uma resposta é uma referência ao código executável, ou um pedaço de código executável, que é passado como um argumento para outro código. Isto 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.
Uma resposta de leigo seria que é uma função que não é chamada por você, mas sim pelo usuário ou pelo navegador depois de um determinado evento ter acontecido ou depois de algum código ter sido processado.
Uma função de callback é uma que deve ser chamada quando uma determinada condição é cumprida. Em vez de ser chamado imediatamente, a função de callback é chamada em um certo ponto no futuro.
Normalmente é usado quando uma tarefa está a ser iniciada que irá terminar assíncronamente (ou seja, terminará algum tempo após a função de chamada ter retornado).
Por exemplo, uma função para solicitar uma página web pode exigir que o seu chamador para fornecer uma função de callback que será chamado quando o a página web terminou o download.
Uma função de callback é uma função que você passa para alguém e deixa eles chamam-lhe em algum momento.Acho que as pessoas acabaram de ler a primeira frase da definição wiki:
Tenho trabalhado com muitas APIs, ver vários maus exemplos. Muitas pessoas tendem a nomear um ponteiro de função(uma referência ao código executável) ou funções anônimas (um pedaço de código executável) "callback", se eles são apenas funções por que você precisa de outro nome para isso?Uma resposta é uma referência ao código executável, ou um pedaço de código executável, que é passado como um argumento para outro codigo.
Na verdade, apenas a segunda frase na definição wiki revela as diferenças entre uma função de callback e uma função normal:
Isto permite que uma camada de software de nível inferior chamar uma sub-rotina (ou função) definida em uma camada de nível superior.
Então a diferença é quem você vai passar a função e como sua função passada vai ser chamada. Se você apenas definir uma função e passá-la para outra função e chamá-la diretamente naquele corpo da função, não chame-a de callback. A definição diz que a tua função passada vai ser chamada por função de nível inferior.
Espero que as pessoas deixem de usar esta palavra num contexto Ambíguo. não posso ajudar as pessoas a entenderem melhor, só que pior.Callbacks são mais facilmente descritos em termos do sistema telefônico. Uma chamada de função é análoga a chamar alguém em um telefone, fazendo-lhe uma pergunta, obtendo uma resposta, e desligando; adicionando um callback muda a analogia para que depois de fazer-lhe uma pergunta, Você também dar-lhe o seu nome e número para que ela possa chamá-lo de volta com a resposta.
-- Paul Jakubik, "implementações de Callback em C++"
Exemplo por parábola e analogia
Tenho uma secretária. Todos os dias lhe peço que: (I) deixe o correio de saída da empresa nos Correios, e Depois ela fez isso, para fazer: (ii) qualquer tarefa que eu escrevi para ela em uma daquelas notas pegajosas . Qual é a tarefa na nota pegajosa? A tarefa varia de dia para dia. Suponha que neste dia em particular, eu ... exigir que ela imprima alguns documentos. Por isso, Anoto isso no bilhete pegajoso, e coloco-o na secretária dela, juntamente com o correio que ela precisa de enviar.Em resumo:
-
Primeiro, ela tem de entregar o correio e ...
- Imediatamente depois disso, ela precisa de imprimir alguns documentos.
A função call back é a segunda tarefa: imprimir esses documentos. Porque é feito depois que o correio é deixado fora, e também porque o sticky note dizendo-lhe para imprimir o documento é dado a ela, juntamente com o e-mail que ela mais precisa.
Vamos agora ligar isto ao vocabulário de programação
- o nome do método neste caso é: DropOffMail.
- e a função de retorno é: documentos impressos. Os documentos impressos são a função call back porque queremos que o secretário faça isso, só depois do DropOffMail ter corrido.
- Então eu "passaria: documentos impressos como um "argumento" para o Método DropOffMail. Este é um ponto importante.
Uma função de callback é uma função que você especifica para uma função/método existente, a ser invocada quando uma ação é concluída, requer processamento adicional, etc.
Em Javascript, ou mais especificamente jQuery, por exemplo, você pode especificar um argumento de callback a ser chamado quando uma animação tiver terminado.
Em PHP, a função preg_replace_callback()
permite-lhe fornecer uma função que será chamada quando a expressão regular for correspondida, passando as cadeias de caracteres correspondentes como argumento.
Chamar depois de seria um nome melhor do que o nome estúpido, callback. Quando ou se a condição é cumprida dentro de uma função, chame outra função, a função chamada após, a que foi recebida como argumento.
Em vez de código-duro uma função interna dentro de uma função, escreve-se uma função para aceitar uma chamada já escrita Após função como argumento. A chamada Após pode ser chamada com base em alterações de Estado detectadas por código na função a receber o argumento.
Olha para a imagem :)
O programa principal chama a função biblioteca (que também pode ser a função do nível do sistema) com o nome da função callback. Esta função de callback pode ser implementada de várias maneiras. O programa principal escolhe um callback de acordo com o requisito.
Finalmente, a função biblioteca chama a função de callback durante a execução.
A resposta simples a esta pergunta é que uma função de callback é uma função que é chamada através de um ponteiro de função. Se você passar o ponteiro (endereço) de uma função como um argumento para outro, quando esse ponteiro é usado para chamar a função que aponta para ele é dito que uma chamada de volta é feita
Suponha que temos uma função sort(int *arraytobesorted,void (*algorithmchosen)(void))
onde ela pode aceitar um ponteiro de função como seu argumento que pode ser usado em algum momento na implementação de sort()
. Então, aqui o código que está sendo endereçado pelo ponteiro da função algorithmchosen
é chamado como função callback .
E ver a vantagem é que podemos escolher qualquer algoritmo como:
1. algorithmchosen = bubblesort
2. algorithmchosen = heapsort
3. algorithmchosen = mergesort ...
Que foram, digamos,implementados com o protótipo:
1. `void bubblesort(void)`
2. `void heapsort(void)`
3. `void mergesort(void)` ...
Este é um conceito usado para alcançar o polimorfismo em Programação Orientada A Objectos
O que é callback?
- Em geral, um telefonema feito para devolver um que alguém recebeu.
- em computação, a callback é um pedaço de código executável que é passado como argumento para outro código. Quando a função é feita com o seu trabalho (ou quando algum evento ocorreu), ela chama a sua função callback (ele chama de volta - daí o nome).
O que é um callback função ?
- uma função de callback é como um servo que" chama de volta " para o seu mestre quando ele completou uma tarefa.
-
A função callback é uma função que é passada para outra função (vamos chamar esta outra função
otherFunction
) como um parâmetro, e a função callback é chamada (ou executada) dentro dootherFunction
.Função acção (x, y, callback) { devolver a resposta (x, y); }
Multiplicação da função (x, y) { devolver x * y; }
Adição de funções (x, y) { devolver x + y; }
Alerta(acção (10, 10, multiplicação)); / / resultado: 100
Alerta(acção (10, 10, adição)); / / resultado: 20
No SOA, o callback permite aos módulos do Plugin aceder aos serviços a partir do contentor/ambiente.
Analogia: Callbacks. Assincrono. Não bloqueador
exemplo da vida Real para callback
" na programação de computadores, uma resposta é uma referência ao código executável, ou um pedaço de código executável, que é passado como um argumento para outro código. Isto 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
Callback em C usando o ponteiro da função
Em C, o callback é implementado usando o ponteiro da função. Ponteiro de função - como o nome sugere, é um ponteiro para uma função.
Para exemplo, int (*ptrFunc) ();
Aqui, o ptrFunc é um ponteiro para uma função que não leva argumentos e devolve um inteiro. Não se esqueça de colocar entre parênteses, caso contrário o compilador irá assumir que ptrFunc é um nome de função normal, que não leva nada e retorna um ponteiro para um inteiro.
Aqui está um código para demonstrar o ponteiro da função.
#include<stdio.h>
int func(int, int);
int main(void)
{
int result1,result2;
/* declaring a pointer to a function which takes
two int arguments and returns an integer as result */
int (*ptrFunc)(int,int);
/* assigning ptrFunc to func's address */
ptrFunc=func;
/* calling func() through explicit dereference */
result1 = (*ptrFunc)(10,20);
/* calling func() through implicit dereference */
result2 = ptrFunc(10,20);
printf("result1 = %d result2 = %d\n",result1,result2);
return 0;
}
int func(int x, int y)
{
return x+y;
}
Agora vamos tentar entender o conceito de Callback em C usando o ponteiro da função.
A o programa completo tem três arquivos: callback.c, reg_callback.h E reg_callback.C.
/* callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* callback function definition goes here */
void my_callback(void)
{
printf("inside my_callback\n");
}
int main(void)
{
/* initialize function pointer to
my_callback */
callback ptr_my_callback=my_callback;
printf("This is a program demonstrating function callback\n");
/* register our callback function */
register_callback(ptr_my_callback);
printf("back inside main program\n");
return 0;
}
/* reg_callback.h */
typedef void (*callback)(void);
void register_callback(callback ptr_reg_callback);
/* reg_callback.c */
#include<stdio.h>
#include"reg_callback.h"
/* registration goes here */
void register_callback(callback ptr_reg_callback)
{
printf("inside register_callback\n");
/* calling our callback function my_callback */
(*ptr_reg_callback)();
}
Se executarmos este programa, a saída será
Este é um programa que demonstra o retorno de funções dentro do registo dentro de my_callback de volta ao programa principal
A função de camada superior chama uma função de camada inferior como uma chamada normal e o mecanismo de callback permite que a função de camada inferior chame a função de camada superior através de um ponteiro para uma chamada de volta funcao.
Callback em Java usando a Interface
Java não tem o conceito de ponteiro de função Implementa o mecanismo de Callback 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 callee terminar a sua tarefa
Deixe-me demonstrá-lo através de um exemplo:A Interface De Chamada De Volta
public interface Callback
{
public void notify(Result result);
}
O chamador ou o Nível Superior Classe
public Class Caller implements Callback
{
Callee ce = new Callee(this); //pass self to the callee
//Other functionality
//Call the Asynctask
ce.doAsynctask();
public void notify(Result result){
//Got the result after the callee has finished the task
//Can do whatever i want with the result
}
}
O Callee ou a função da camada inferior
public Class Callee {
Callback cb;
Callee(Callback cb){
this.cb = cb;
}
doAsynctask(){
//do the long running task
//get the result
cb.notify(result);//after the task is completed, notify the caller
}
}
Callback usando o padrão EventListener
- rubrica da lista
Este padrão é usado para notificar 0 a n números de observadores / ouvintes que uma determinada tarefa terminou
- rubrica da lista
A Interface Do Evento
public interface Events {
public void clickEvent();
public void longClickEvent();
}
Elemento Da Classe
package com.som_itsolutions.training.java.exampleeventlistener;
import java.util.ArrayList;
import java.util.Iterator;
public class Widget implements Events{
ArrayList<OnClickEventListener> mClickEventListener = new ArrayList<OnClickEventListener>();
ArrayList<OnLongClickEventListener> mLongClickEventListener = new ArrayList<OnLongClickEventListener>();
@Override
public void clickEvent() {
// TODO Auto-generated method stub
Iterator<OnClickEventListener> it = mClickEventListener.iterator();
while(it.hasNext()){
OnClickEventListener li = it.next();
li.onClick(this);
}
}
@Override
public void longClickEvent() {
// TODO Auto-generated method stub
Iterator<OnLongClickEventListener> it = mLongClickEventListener.iterator();
while(it.hasNext()){
OnLongClickEventListener li = it.next();
li.onLongClick(this);
}
}
public interface OnClickEventListener
{
public void onClick (Widget source);
}
public interface OnLongClickEventListener
{
public void onLongClick (Widget source);
}
public void setOnClickEventListner(OnClickEventListener li){
mClickEventListener.add(li);
}
public void setOnLongClickEventListner(OnLongClickEventListener li){
mLongClickEventListener.add(li);
}
}
Botão Da Classe
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
Opção De Classe
public class CheckBox extends Widget{
private boolean checked;
public CheckBox() {
checked = false;
}
public boolean isChecked(){
return (checked == true);
}
public void setCheck(boolean checked){
this.checked = checked;
}
}
Classe De Actividade
Pacote suplemento.som_itsolutions.formacao.hipoteca.exampleeventlistener;
public class Activity implements Widget.OnClickEventListener
{
public Button mButton;
public CheckBox mCheckBox;
private static Activity mActivityHandler;
public static Activity getActivityHandle(){
return mActivityHandler;
}
public Activity ()
{
mActivityHandler = this;
mButton = new Button();
mButton.setOnClickEventListner(this);
mCheckBox = new CheckBox();
mCheckBox.setOnClickEventListner(this);
}
public void onClick (Widget source)
{
if(source == mButton){
mButton.setButtonText("Thank you for clicking me...");
System.out.println(((Button) mButton).getButtonText());
}
if(source == mCheckBox){
if(mCheckBox.isChecked()==false){
mCheckBox.setCheck(true);
System.out.println("The checkbox is checked...");
}
else{
mCheckBox.setCheck(false);
System.out.println("The checkbox is not checked...");
}
}
}
public void doSomeWork(Widget source){
source.clickEvent();
}
}
Outras Classes
public class OtherClass implements Widget.OnClickEventListener{
Button mButton;
public OtherClass(){
mButton = Activity.getActivityHandle().mButton;
mButton.setOnClickEventListner(this);//interested in the click event //of the button
}
@Override
public void onClick(Widget source) {
if(source == mButton){
System.out.println("Other Class has also received the event notification...");
}
}
Classe Principal
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Activity a = new Activity();
OtherClass o = new OtherClass();
a.doSomeWork(a.mButton);
a.doSomeWork(a.mCheckBox);
}
}
Como pode ver no código acima, temos uma interface chamada eventos que basicamente lista todos os eventos que podem acontecer para a nossa aplicação. A classe Widget é a classe base para todos os componentes UI como botão, Checkbox. Estes componentes UI são os objetos que realmente recebem os Eventos do Código-quadro. A classe Widget implementa a interface de Eventos e também tem duas interfaces aninhadas, nomeadamente o onclick EventListener & OnLongClickEventListener
Estas duas interfaces são responsáveis por ouvir os eventos que podem ocorrer nos componentes UI derivados do elemento, como o botão ou a opção. Então, se compararmos este exemplo com o exemplo anterior de Callback usando interface Java, estas duas interfaces funcionam como interface de Callback. Assim, o código de nível superior (atividade aqui) implementa estes dois interface. E sempre que um evento ocorre para um widget, o código de nível mais elevado (ou o método destas interfaces implementadas no código de nível mais elevado, que é aqui atividade) será chamado.
Agora deixe-me discutir a diferença básica entre Callback e padrão Eventlistener. Como mencionamos que usando Callback, o Callee pode notificar apenas um ouvinte. Mas no caso de padrão EventListener, qualquer outra parte ou classe da aplicação pode se registrar para os eventos que podem ocorrer no botão ou opção. O exemplo deste tipo de classe é a outra classe. Se você ver o código da outra classe, você vai descobrir que ela se registrou como um ouvinte para o ClickEvent que pode ocorrer no botão definido na atividade. Parte interessante é que, além da atividade ( o chamador), esta outra classe também será notificada sempre que o evento clique ocorre no botão.Uma área de Utilização importante é que você regista uma das suas funções como um cabo (ou seja, uma chamada de resposta) e depois envia uma mensagem / chamada de alguma função para fazer algum trabalho ou processamento. Agora, após o processamento é feito, a função chamada chamaria a nossa função registrada (ou seja, agora a chamada de volta é feita), indicando assim que o processamento dos EUA é feito.
Este link da Wikipédia explica bastante bem graficamente.
Uma função de callback, também conhecida como uma função de ordem superior, é uma função que é passada para outra função como um parâmetro, e a função de callback é chamada (ou executada) dentro da função-mãe.
$("#button_1").click(function() {
alert("button 1 Clicked");
});
Aqui passamos uma função como parâmetro para o método click. E o método click irá chamar (ou executar) a função de callback que passamos para ele.
Função De Callback Uma função que passou para outra função como argumento.
function test_function(){
alert("Hello world");
}
setTimeout(test_function, 2000);
Nota: no exemplo acima, test_function usado como argumento para a função setTimeout.
Uma função de callback é uma função que você passa (como uma referência ou um ponteiro) para uma determinada função ou objeto. Esta função ou objeto irá chamar esta função de volta a qualquer momento mais tarde, possivelmente várias vezes, para qualquer tipo de propósito:
- notificar o fim de uma tarefa
- solicito comparação entre dois itens (como em C qsort ())
- comunicação dos progressos de um processo
- a notificar eventos
- delegando a instanciação de um objecto Delegação a pintura de uma área
...
Descrever um callback como uma função que está sendo chamada no final de outra função ou tarefa é excessivamente simplificando (mesmo que seja um caso de uso comum).