¿Qué es una función de devolución de llamada?
¿Qué es una función de devolución de llamada?
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:
// 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 si llamó a event ():
The number you provided is: 6
I have finished printing numbers.
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.)
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 una callback
función?
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.
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 de 5!
, invocaría factorial(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 llegar
La 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 suyo
Si elige la segunda opción, las devoluciones de llamada podrían funcionar para usted.
Para explotar un patrón de devolución de llamada, lo que desea es poder llamar factorial
de la siguiente manera:
factorial(really_big_number, what_to_do_with_the_result)
El segundo parámetro, what_to_do_with_the_result
es una función a la que envía factorial
, con la esperanza de que factorial
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 tanto factorial
, 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í:
factorial (number, callback, params)
{
result = number! // i can make up operators in my pseudocode
callback (result, params)
}
Ahora que factorial
permite este patrón, su devolución de llamada podría verse así:
logIt (number, logger)
{
logger.log(number)
}
y tu llamada factorial
sería
factorial(42, logIt, logger)
¿Qué pasa si quieres devolver algo logIt
? Bueno, no puedes, porque factorial
no le estás prestando atención.
Bueno, ¿por qué no puede factorial
devolver lo que devuelve su devolución de llamada?
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:
factorial(param_1, param_2, ...)
{
new factorial_worker_task(param_1, param_2, ...);
return;
}
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.
La respuesta es permanecer dentro del patrón de devolución de llamada. Cuando quieras escribir
a = f()
g(a)
y f
se llamará asincrónicamente, en su lugar escribirá
f(g)
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 como print (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
f( func(a) { print(2*a+1); })
que es mucho mejor
¿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.
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.
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:
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.
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.
"...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 ++"
Creo que esta jerga de "devolución de llamada" se ha utilizado por error en muchos lugares. Mi definición sería algo como:
Una función de devolución de llamada es una función que le pasa a alguien y le permite llamarla en algún momento.
Creo que la gente acaba de leer la primera oración de la definición de wiki:
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.
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:
Esto permite que una capa de software de nivel inferior llame a una subrutina (o función) definida en una capa de nivel superior.
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.
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.
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?
¿Qué es la devolución de llamada ?
¿Qué es una función de devolución de llamada ?
otherFunction
) como un parámetro, y la función de devolución de llamada se llama (o ejecuta) dentro del otherFunction
. function action(x, y, callback) {
return callback(x, y);
}
function multiplication(x, y) {
return x * y;
}
function addition(x, y) {
return x + y;
}
alert(action(10, 10, multiplication)); // output: 100
alert(action(10, 10, addition)); // output: 20
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
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.
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.
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.
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
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 de sort()
la implementación. Entonces, aquí el código al que se dirige el puntero de función algorithmchosen
se llama como función de devolución de llamada .
Y ver la ventaja es que podemos elegir cualquier algoritmo como:
1. algorithmchosen = bubblesort
2. algorithmchosen = heapsort
3. algorithmchosen = mergesort ...
Los cuales, por ejemplo, se han implementado con el prototipo:
1. `void bubblesort(void)`
2. `void heapsort(void)`
3. `void mergesort(void)` ...
Este es un concepto utilizado para lograr el polimorfismo en la programación orientada a objetos.
“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.
#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;
}
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.
/* 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)();
}
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
public interface Callback
{
public void notify(Result result);
}
La persona que llama o la clase de nivel superior
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
}
}
La función Callee o la capa 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
}
}
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
public interface Events {
public void clickEvent();
public void longClickEvent();
}
Widget de clase
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ón de clase
public class Button extends Widget{
private String mButtonText;
public Button (){
}
public String getButtonText() {
return mButtonText;
}
public void setButtonText(String buttonText) {
this.mButtonText = buttonText;
}
}
Casilla de verificación de clase
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;
}
}
Clase de actividad
paquete com.som_itsolutions.training.java.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();
}
}
Otra clase
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...");
}
}
Clase 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 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.
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).
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 ...).
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.
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.
$("#button_1").click(function() {
alert("button 1 Clicked");
});
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.
Función de devolución de llamada Una función que pasó a otra función como argumento.
function test_function(){
alert("Hello world");
}
setTimeout(test_function, 2000);
Nota: En el ejemplo anterior, test_function se usa como argumento para la función setTimeout.