¿Qué es una función de devolución de llamada?
language-agnostic
callback
Cheekysoft
fuente
fuente
Respuestas:
Los desarrolladores a menudo se confunden por lo que es una devolución de llamada debido al nombre de la maldita cosa.
Una función de devolución de llamada es una función que es:
Una buena manera de imaginar cómo funciona una función de devolución de llamada es que es una función que se " llama en la parte posterior " de la función a la que se pasa.
Tal vez un mejor nombre sería una función de "llamada después" .
Esta construcción es muy útil para el comportamiento asíncrono donde queremos que tenga lugar una actividad cada vez que se completa un evento anterior.
Pseudocódigo:
Resultado si llamó a event ():
El orden de la salida aquí es importante. Dado que las funciones de devolución de llamada se llaman después, "He terminado de imprimir números" se imprime en último lugar, no primero.
Las devoluciones de llamada se denominan debido a su uso con idiomas de puntero. Si no usa uno de esos, no trabaje con el nombre 'devolución de llamada'. Solo comprenda que es solo un nombre para describir un método que se proporciona como argumento para otro método, de modo que cuando se llama al método principal (cualquier condición, como un clic en un botón, un tic del temporizador, etc.) y su cuerpo del método se completa, se invoca la función de devolución de llamada.
Algunos idiomas admiten construcciones en las que se admiten múltiples argumentos de función de devolución de llamada, y se invocan en función de cómo se completa la función principal (es decir, se llama a una devolución de llamada en caso de que la función principal se complete con éxito, se llama a otra en caso de que la función principal arroje un error específico, etc.)
fuente
once its parent method completes, the function which this argument represents is then called
. Entonces, si la función se pasa a otra función como argumento pero se llama desde la mitad del tiempo de ejecución de la función principal, ¿parent(cb) {dostuff1(); cb(); dostuff2()}
entonces no se considera unacallback
función?Definición opaca
Una función de devolución de llamada es una función que usted proporciona a otro fragmento de código, lo que le permite ser invocado por ese código.
Ejemplo contribuido
Por qué querrías hacer esto? Digamos que hay un servicio que necesita invocar. Si el servicio regresa de inmediato, simplemente:
Por ejemplo, supongamos que el servicio fuera la
factorial
función. Cuando desee el valor de5!
, invocaríafactorial(5)
y se darían los siguientes pasos:Su ubicación de ejecución actual se guarda (en la pila, pero eso no es importante)
La ejecución se entrega a
factorial
Cuando se
factorial
completa, coloca el resultado en algún lugar al que pueda llegarLa ejecución vuelve a donde estaba [1]
Ahora suponga que
factorial
tomó mucho tiempo, porque le está dando grandes cantidades y necesita ejecutarse en algún clúster de supercomputación en algún lugar. Digamos que espera que le tome 5 minutos devolver su resultado. Tú podrías:Mantenga su diseño y ejecute su programa por la noche cuando esté dormido, para que no esté mirando la pantalla la mitad del tiempo
Diseñe su programa para hacer otras cosas mientras
factorial
hace lo suyoSi elige la segunda opción, las devoluciones de llamada podrían funcionar para usted.
Diseño de extremo a extremo
Para explotar un patrón de devolución de llamada, lo que desea es poder llamar
factorial
de la siguiente manera:El segundo parámetro,
what_to_do_with_the_result
es una función a la que envíafactorial
, con la esperanza de quefactorial
lo llame a su resultado antes de regresar.Sí, esto significa que
factorial
debe haber sido escrito para admitir devoluciones de llamada.Ahora suponga que desea poder pasar un parámetro a su devolución de llamada. Ahora no puedes, porque no lo vas a llamar,
factorial
es. Por lo tantofactorial
, debe escribirse para permitirle pasar sus parámetros, y simplemente los entregará a su devolución de llamada cuando lo invoque. Podría verse así:Ahora que
factorial
permite este patrón, su devolución de llamada podría verse así:y tu llamada
factorial
sería¿Qué pasa si quieres devolver algo
logIt
? Bueno, no puedes, porquefactorial
no le estás prestando atención.Bueno, ¿por qué no puede
factorial
devolver lo que devuelve su devolución de llamada?Haciéndolo sin bloqueo
Dado que la ejecución debe entregarse a la devolución de llamada cuando
factorial
finalice, realmente no debería devolver nada a la persona que llama. E idealmente, de alguna manera iniciaría su trabajo en otro hilo / proceso / máquina y regresaría de inmediato para que pueda continuar, tal vez algo como esto:Esta es ahora una "llamada asincrónica", lo que significa que cuando la llamas, regresa de inmediato pero aún no ha hecho su trabajo. Por lo tanto, necesita mecanismos para verificarlo y obtener su resultado cuando finalice, y su programa se ha vuelto más complejo en el proceso.
Y, por cierto, utilizando este patrón,
factorial_worker_task
puede iniciar su devolución de llamada de forma asincrónica y regresar de inmediato.Entonces, ¿Qué haces?
La respuesta es permanecer dentro del patrón de devolución de llamada. Cuando quieras escribir
y
f
se llamará asincrónicamente, en su lugar escribirádonde
g
se pasa como una devolución de llamada.Esto cambia fundamentalmente la topología de flujo de su programa y lleva un tiempo acostumbrarse.
Su lenguaje de programación podría ayudarlo mucho al brindarle una forma de crear funciones sobre la marcha. En el código inmediatamente anterior, la función
g
puede ser tan pequeña comoprint (2*a+1)
. Si su idioma requiere que defina esto como una función separada, con un nombre y una firma completamente innecesarios, entonces su vida se volverá desagradable si usa mucho este patrón.Si, por otro lado, tu idioma te permite crear lambdas, entonces estás en mejor forma. Luego terminarás escribiendo algo como
que es mucho mejor
Cómo pasar la devolución de llamada
¿Cómo pasarías la función de devolución de llamada
factorial
? Bueno, podrías hacerlo de varias maneras.Si la función llamada se ejecuta en el mismo proceso, puede pasar un puntero de función
O tal vez desee mantener un diccionario de
fn name --> fn ptr
en su programa, en cuyo caso podría pasar el nombre¡Quizás su lenguaje le permita definir la función en el lugar, posible como una lambda! Internamente está creando algún tipo de objeto y pasando un puntero, pero no tiene que preocuparse por eso.
Quizás la función que está llamando se ejecuta en una máquina completamente separada, y la está llamando usando un protocolo de red como HTTP. Puede exponer su devolución de llamada como una función invocable HTTP y pasar su URL.
Tienes la idea.
El reciente aumento de las devoluciones de llamada
En esta era web en la que hemos ingresado, los servicios que invocamos a menudo se realizan a través de la red. A menudo no tenemos ningún control sobre esos servicios, es decir, no los escribimos, no los mantenemos, no podemos asegurarnos de que estén funcionando o de cómo están funcionando.
Pero no podemos esperar que nuestros programas se bloqueen mientras esperamos que estos servicios respondan. Teniendo esto en cuenta, los proveedores de servicios a menudo diseñan API utilizando el patrón de devolución de llamada.
JavaScript admite devoluciones de llamada muy bien, por ejemplo, con lambdas y cierres. Y hay mucha actividad en el mundo de JavaScript, tanto en el navegador como en el servidor. Incluso se están desarrollando plataformas JavaScript para dispositivos móviles.
A medida que avanzamos, más y más de nosotros escribiremos código asincrónico, para lo cual esta comprensión será esencial.
fuente
Tenga en cuenta que la devolución de llamada es una palabra.
La página de devolución de llamada de Wikipedia lo explica muy bien.
cita de la página de wikipedia:
fuente
Una respuesta simple sería que es una función que no es invocada por usted, sino por el usuario o por el navegador después de que cierto evento haya sucedido o después de que se haya procesado algún código.
fuente
Una función de devolución de llamada es aquella que debe llamarse cuando se cumple una determinada condición. En lugar de ser llamado de inmediato, la función de devolución de llamada se llama en un momento determinado en el futuro.
Por lo general, se usa cuando se inicia una tarea que finalizará de forma asincrónica (es decir, finalizará algún tiempo después de que la función de llamada haya regresado).
Por ejemplo, una función para solicitar una página web puede requerir que la persona que llama proporcione una función de devolución de llamada que se llamará cuando la página web haya finalizado la descarga.
fuente
"...when a condition is met"
pero pensé que las devoluciones de llamada se llaman cuando la función principal termina de ejecutarse y no dependen de las condiciones (?).Las devoluciones de llamada se describen más fácilmente en términos del sistema telefónico. Una llamada de función es análoga a llamar a alguien por teléfono, hacerle una pregunta, obtener una respuesta y colgar; agregar una devolución de llamada cambia la analogía para que después de hacerle una pregunta, también le dé su nombre y número para que pueda devolverle la llamada con la respuesta.
- Paul Jakubik, "Implementaciones de devolución de llamada en C ++"
fuente
Creo que esta jerga de "devolución de llamada" se ha utilizado por error en muchos lugares. Mi definición sería algo como:
Creo que la gente acaba de leer la primera oración de la definición de wiki:
He estado trabajando con muchas API, veo varios ejemplos malos. Muchas personas tienden a nombrar un puntero de función (una referencia al código ejecutable) o funciones anónimas (una pieza de código ejecutable) "devolución de llamada", si son solo funciones, ¿por qué necesita otro nombre para esto?
En realidad, solo la segunda oración en la definición de wiki revela las diferencias entre una función de devolución de llamada y una función normal:
así que la diferencia es a quién va a pasar la función y cómo se llamará a su función pasada. Si solo define una función y la pasa a otra función y la llamó directamente en ese cuerpo de función, no la llame devolución de llamada. La definición dice que su función aprobada será llamada por la función de "nivel inferior".
Espero que la gente pueda dejar de usar esta palabra en un contexto ambiguo, no puede ayudar a las personas a entender mejor, solo peor.
fuente
Hagámoslo simple. ¿Qué es una función de devolución de llamada?
Ejemplo por parábola y analogía
Tengo una secretaria Todos los días le pido que: (i) deje el correo saliente de la empresa en la oficina de correos, y después de que lo haya hecho, haga: (ii) cualquier tarea que le escribí en una de esas notas adhesivas .
Ahora, ¿cuál es la tarea en la nota adhesiva? La tarea varía de un día a otro.
Supongamos que en este día en particular, le exijo que imprima algunos documentos. Así que lo escribo en la nota adhesiva, y lo pongo en su escritorio junto con el correo saliente que necesita publicar.
En resumen:
La función de devolución de llamada es esa segunda tarea: imprimir esos documentos. Debido a que se hace DESPUÉS de que se deja el correo, y también porque se le entrega la nota adhesiva que le dice que imprima el documento junto con el correo que necesita publicar.
Ahora relacionemos esto con el vocabulario de programación
Eso es todo lo que es. Nada mas. Espero que eso lo haya aclarado, y si no, publique un comentario y haré todo lo posible para aclararlo.
fuente
Esto hace que las devoluciones de llamada suenen como declaraciones de retorno al final de los métodos.
No estoy seguro de que sean eso.
Creo que las devoluciones de llamada son en realidad una llamada a una función, como consecuencia de que se invoca y completa otra función.
También creo que las devoluciones de llamada están destinadas a abordar la invocación de origen, en una especie de "¡oye! ¿Qué es lo que pediste?
fuente
otherFunction
) como un parámetro, y la función de devolución de llamada se llama (o ejecuta) dentro delotherFunction
.En SOA, la devolución de llamada permite que los módulos de complemento accedan a los servicios desde el contenedor / entorno.
Analogía: devoluciones de llamada. Asincrónico. Ejemplo de la vida real sin bloqueo
para devolución de llamada
fuente
Call After sería un nombre mejor que el nombre estúpido, callback . Cuando o si la condición se cumple dentro de una función, llame a otra función, la función Llamar después , la recibida como argumento.
En lugar de codificar una función interna dentro de una función, se escribe una función para aceptar una función Call After ya escrita como argumento. Se puede llamar a Call After en función de los cambios de estado detectados por el código en la función que recibe el argumento.
fuente
Una función de devolución de llamada es una función que usted especifica a una función / método existente, que se invoca cuando se completa una acción, requiere un procesamiento adicional, etc.
En Javascript, o más específicamente jQuery, por ejemplo, puede especificar un argumento de devolución de llamada que se llamará cuando haya finalizado una animación.
En PHP, la
preg_replace_callback()
función le permite proporcionar una función que se llamará cuando se coincida la expresión regular, pasando la (s) cadena (s) coincidentes como argumentos.fuente
mira la imagen :)
El programa principal llama a la función de biblioteca (que también podría ser una función de nivel de sistema) con el nombre de la función de devolución de llamada. Esta función de devolución de llamada podría implementarse de varias maneras. El programa principal elige una devolución de llamada según el requisito.
Finalmente, la función de biblioteca llama a la función de devolución de llamada durante la ejecución.
fuente
La respuesta simple a esta pregunta es que una 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 argumento a otra, cuando ese puntero se usa para llamar a la función a la que apunta, se dice que se realiza una devolución de llamada
fuente
Supongamos que tenemos una función
sort(int *arraytobesorted,void (*algorithmchosen)(void))
en la que puede aceptar un puntero de función como argumento que puede usarse en algún momento desort()
la implementación. Entonces, aquí el código al que se dirige el puntero de funciónalgorithmchosen
se llama como función de devolución de llamada .Y ver la ventaja es que podemos elegir cualquier algoritmo como:
Los cuales, por ejemplo, se han implementado con el prototipo:
Este es un concepto utilizado para lograr el polimorfismo en la programación orientada a objetos.
fuente
“En la programación de computadoras, una devolución de llamada es una referencia al código ejecutable, o un fragmento de código ejecutable, que se 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 ". - Wikipedia
Devolución de llamada en C usando el puntero de función
En C, la devolución de llamada se implementa utilizando el puntero de función. Puntero de función: como su nombre indica, es un puntero a una función.
Por ejemplo, int (* ptrFunc) ();
Aquí, ptrFunc es un puntero a una función que no toma argumentos y devuelve un entero. NO olvide poner el paréntesis, de lo contrario, el compilador supondrá que ptrFunc es un nombre de función normal, que no toma nada y devuelve un puntero a un entero.
Aquí hay un código para demostrar el puntero de la función.
Ahora intentemos comprender el concepto de devolución de llamada en C usando el puntero de función.
El programa completo tiene tres archivos: callback.c, reg_callback.h y reg_callback.c.
Si ejecutamos este programa, la salida será
Este es un programa que muestra la función de devolución de llamada dentro de register_callback dentro de my_callback dentro del programa principal
La función de capa superior llama a una función de capa inferior como una llamada normal y el mecanismo de devolución de llamada permite que la función de capa inferior llame a la función de capa superior a través de un puntero a una función de devolución de llamada.
Devolución de llamada en Java usando la interfaz
Java no tiene el concepto de puntero de función Implementa el mecanismo de devolución de llamada a través de su mecanismo de interfaz Aquí, en lugar de un puntero de función, declaramos que una interfaz tiene un método que se llamará cuando el destinatario finalice su tarea
Permítanme demostrarlo a través de un ejemplo:
La interfaz de devolución de llamada
La persona que llama o la clase de nivel superior
La función Callee o la capa inferior
Devolución de llamada utilizando el patrón EventListener
Este patrón se utiliza para notificar de 0 a n números de observadores / oyentes que una tarea en particular ha finalizado
La diferencia entre el mecanismo de devolución de llamada y el mecanismo EventListener / Observer es que en la devolución de llamada, la persona que llama notifica a la persona que llama, mientras que en Eventlisener / Observer, la persona que llama puede notificar a cualquier persona interesada en ese evento (la notificación puede ir a otras partes del aplicación que no ha activado la tarea)
Déjame explicarte a través de un ejemplo.
La interfaz de eventos
Widget de clase
Botón de clase
Casilla de verificación de clase
Clase de actividad
paquete com.som_itsolutions.training.java.exampleeventlistener;
Otra clase
Clase principal
Como puede ver en el código anterior, tenemos una interfaz llamada eventos que básicamente enumera todos los eventos que pueden ocurrir para nuestra aplicación. La clase Widget es la clase base para todos los componentes de la interfaz de usuario, como Button, Checkbox. Estos componentes de la interfaz de usuario son los objetos que realmente reciben los eventos del código marco. La clase de widget implementa la interfaz de eventos y también tiene dos interfaces anidadas, OnClickEventListener y OnLongClickEventListener
Estas dos interfaces son responsables de escuchar los eventos que pueden ocurrir en los componentes de la interfaz de usuario derivados del widget como Button o Checkbox. Entonces, si comparamos este ejemplo con el ejemplo anterior de devolución de llamada utilizando la interfaz Java, estas dos interfaces funcionan como la interfaz de devolución de llamada. Entonces el código de nivel superior (Here Activity) implementa estas dos interfaces. Y cada vez que se produzca un evento en un widget, se llamará al código de nivel superior (o al método de estas interfaces implementado en el código de nivel superior, que es aquí Actividad).
Ahora déjenme discutir la diferencia básica entre Callback y el patrón Eventlistener. Como hemos mencionado que usando la devolución de llamada, la persona que llama puede notificar solo a una sola persona que llama. Pero en el caso del patrón EventListener, cualquier otra parte o clase de la Aplicación puede registrarse para los eventos que pueden ocurrir en el Botón o Casilla de verificación. El ejemplo de este tipo de clase es el OtherClass. Si ve el código de la Otra Clase, encontrará que se ha registrado como un oyente del ClickEvent que puede ocurrir en el Botón definido en la Actividad. La parte interesante es que, además de la Actividad (la persona que llama), esta Otra Clase también se notificará cada vez que ocurra el evento de clic en el Botón.
fuente
Una función de devolución de llamada es una función que pasa (como referencia o puntero) a una determinada función u objeto. Esta función u objeto volverá a llamar a esta función en cualquier momento posterior, posiblemente varias veces, para cualquier tipo de propósito:
...
Por lo tanto, describir una devolución de llamada como una función que se llama al final de otra función o tarea es demasiado simplificado (incluso si es un caso de uso común).
fuente
Una devolución de llamada es una idea de pasar una función como parámetro a otra función y hacer que se invoque una vez que el proceso se haya completado.
Si obtiene el concepto de devolución de llamada a través de respuestas impresionantes anteriores, le recomiendo que conozca los antecedentes de su idea.
"¿Qué los hizo (informáticos) desarrollar devolución de llamada?" Es posible que aprenda un problema, que es el bloqueo (especialmente el bloqueo de la interfaz de usuario) y la devolución de llamada no es la única solución. Hay muchas otras soluciones (por ejemplo: Hilo, Futuros, Promesas ...).
fuente
Un área de uso importante es que registre una de sus funciones como identificador (es decir, una devolución de llamada) y luego envíe un mensaje / llame a alguna función para realizar algún trabajo o procesamiento. Ahora, después de que se realiza el procesamiento, la función llamada llamará a nuestra función registrada (es decir, ahora se realiza la devolución de llamada), lo que nos indica que el procesamiento está hecho.
Este enlace de wikipedia explica bastante bien gráficamente.
fuente
Una función de devolución de llamada, también conocida como función de orden superior, es una función que se pasa a otra función como parámetro, y la función de devolución de llamada se llama (o ejecuta) dentro de la función principal.
Aquí hemos pasado una función como parámetro al método de clic. Y el método click llamará (o ejecutará) la función de devolución de llamada que le pasamos.
fuente
Función de devolución de llamada Una función que pasó a otra función como argumento.
Nota: En el ejemplo anterior, test_function se usa como argumento para la función setTimeout.
fuente