2010-12-01 14 views

Respuesta

19

La devolución de llamada es algo que pasa a una función, que le indica cómo debe llamar en algún momento de su funcionamiento. El código en la función decide cuándo llamar a la función (y qué argumentos aprobar). Normalmente, la forma de hacerlo es pasar la función en sí como la 'devolución de llamada', en idiomas donde las funciones son objetos. En otros idiomas, puede que tenga que pasar algún tipo de cosa especial llamada "puntero de función" (o similar); o puede que tenga que pasar el nombre de la función (que luego se busca en el tiempo de ejecución).

Un ejemplo trivial, en Python:

void call_something_three_times(what_to_call, what_to_pass_it): 
    for i in xrange(3): what_to_call(what_to_pass_it) 

# Write "Hi mom" three times, using a callback. 
call_something_three_times(sys.stdout.write, "Hi mom\n") 

En este ejemplo vamos a separar la tarea de repetir una llamada de función, de la tarea de llamar a la función realidad. Eso no es muy útil, pero demuestra el concepto.

En el mundo real, las devoluciones de llamadas se utilizan mucho para cosas como el enhebrado de bibliotecas, donde se llama a alguna función de creación de subprocesos con una devolución de llamada que describe el trabajo que hará el subproceso. La función de creación de subprocesos hace el trabajo necesario para configurar un subproceso, y luego organiza la llamada de la función de devolución de llamada por el nuevo subproceso.

5

La función de devolución de llamada es una función que se llama a través de un puntero de función. Si pasa el puntero (dirección) de una función como un argumento a otro, cuando ese puntero se usa para llamar a la función que apunta, se dice que se realiza una devolución de llamada.

¿Por qué debería utilizar las funciones de devolución de llamada?

Se puede usar una devolución de llamada para las notificaciones. Por ejemplo, necesita configurar un temporizador en su aplicación. Cada vez que el temporizador expira, su aplicación debe ser notificada. Pero el implementador del mecanismo de temporizadores no sabe nada sobre su aplicación. Solo quiere un puntero a una función con un prototipo dado, y al usar ese puntero realiza una devolución de llamada, notificando a su aplicación sobre el evento que ha ocurrido. De hecho, el SetTimer() WinAPI utiliza una función de devolución de llamada para notificar que el temporizador ha expirado (y, en caso de que no haya una función de devolución de llamada provista, publica un mensaje en la cola de la aplicación).

+0

No todos los idiomas tienen punteros a las funciones. –

+3

@Ignacio: Cualquier lenguaje que permita devoluciones de llamada tendrá un puntero de función de alguna forma. Podría esconderse bajo el disfraz de una interfaz o una función virtual, sobrecargada, anulada (o como quiera que los diseñadores del lenguaje lo quieran llamar), pero en algún lugar a lo largo de la línea habrá un comando "saltar" o "llamar" que toma su el destino de una variable en ram en lugar de código fijo en el conjunto (ya sea código de "ensamblado" de VM o código de ensamblado de CPU). –

1

En general, se proporciona una función como parámetro que se invoca cuando ocurre algo.

En código C se pasa a algo que se parece a esto:

int (callback *)(void *, long); 

es decir una función que toma dos parámetros, void * y largas y devuelve un int.

En los lenguajes orientados a objetos, la sintaxis es a veces más simple. Por ejemplo, es posible que pueda construir un mecanismo de devolución de llamada que le permita al usuario pasar un objeto que se parece a una función o tiene un método abstracto (envolviendo así una función) y también datos de contexto.

Los idiomas modernos usan el término "delegado" para referirse a una función "patrón". Estos se pueden usar como devoluciones de llamada. Algunos lenguajes también usan el término lambda que es esencialmente una función sin nombre, a menudo creada "sobre la marcha" en un bloque de código y pasada como una devolución de llamada. C++11 ha introducido esto en su estándar.

La ventaja de utilizar una devolución de llamada es que puede separar, es decir, reducir/desacoplar una API de lo que la llama y, hasta cierto punto, viceversa, es decir, aunque en un lugar sabe que está llamando a la API. en el punto del "manejador" no necesita saber de dónde se llamó.

Por ejemplo, puede tener una API que genere objetos y luego "llamadas devueltas" a medida que se generan.

0

La devolución de llamada significa que pasa el código como parámetro. Por ejemplo, imagina un botón, que muestran una gran parte de diálogo cuando se pulsa:

Button testBtn; 
testBtn.setOnClickListener(new OnClickListener() { 

    @Override 
    public void onCLick() { 
    JOptionPane.showDialog(testBtn, "Test button pressed"); 
    } 
} 

Aquí nos dicen lo que el botón para ejecutar, cuando se haga clic. Entonces, el framework ejecutará el código pasado, cuando detecte el clic. Dentro del marco hay algo de código como:

void processEvent(Event e) { 
    if (e.type == Event.CLICK) { 
    e.getComponent().getOnClickListener().onClick(); 
    } 
} 

Por lo tanto, un cierto código básico llama de nuevo al oyente cuando el evento ocurre apropiada.

PD: Pseudocódigo aquí, simplemente describe la idea.

10

Wiki dice:

En la programación informática, una devolución de llamada es una referencia al código ejecutable, o una pieza de código ejecutable , es decir pasa como argumento a otro código. Esto permite que una capa de software de nivel inferior llame a una subrutina (o función ) definida en una capa de nivel superior .

En términos comunes, es el mecanismo para notificar una parte de código, es decir, un método, qué parte de código ejecutar, es decir, otro método, cuando es necesario.
La devolución de llamada está relacionada con el hecho de que el cliente de la función de llamada especifica una función que pertenece a la función de ejecución de la función de llamada del código del cliente y se pasa como un argumento.
Un ejemplo se encuentra en las GUI. Usted pasa como argumento la función a ser llamada una vez que ocurre un evento (por ejemplo, botón presionado) y una vez que ocurre el evento se llama a esta función.
Esta función generalmente es implementada por el objeto que se registró originalmente para el evento

Cuestiones relacionadas