1. Definición de función de devolución de llamada
Una función de devolución de llamada es una función llamada a través de un puntero de función. Si pasa el puntero (dirección) de la función como un argumento a otra función, cuando este puntero se usa para llamar a la función a la que señala, decimos que esta es una función de devolución de llamada. La función de devolución de llamada no es llamada directamente por el implementador de la función, sino que otra parte llama cuando ocurre un evento o condición específico, y se utiliza para responder al evento o condición.
En JavaScript, la definición específica de la función de devolución de llamada es: la función A se pasa como un parámetro (referencia de función) en otra función B, y esta función B ejecuta la función A. Supongamos que la función A se llama función de devolución de llamada. Si no hay nombre (expresión de funciones), se llama una función de devolución de llamada anónima. Por lo tanto, la devolución de llamada no se usa necesariamente para la asíncrona. Las devoluciones de llamada a menudo se usan en escenarios sincrónicos (bloqueo) generales, como exigir que se ejecuten algunas operaciones y se ejecute la función de devolución de llamada.
ejemplo
Un ejemplo del uso de devoluciones de llamada en sincronización (bloqueo) es ejecutar FUNC2 después de ejecutar el código FUNC1.
var func1 = function (devolución de llamada) {// Haz algo. (Callback && typeOf (llamado) === "function") && callback ();} func1 (func2); var func2 = function () {}2. Use ocasiones de la función de devolución de llamada
Carga de recursos: ejecute la devolución de llamada después de la carga dinámica de los archivos JS, ejecute la devolución de llamada después de cargar iframe, ejecute la devolución de llamada después de cargar la devolución de llamada de la operación AJAX, ejecute la devolución de llamada después de la carga de la imagen, AJAX, etc.
Los eventos DOM y los eventos node.js se basan en el mecanismo de devolución de llamada (las devoluciones de llamada Node.js pueden tener problemas de anidación de devolución de llamada de varias capas).
El tiempo de retraso de SetTimeout es 0. Este truco a menudo se usa. La función llamada por setTimeout es en realidad una realización de devolución de llamada
Llamada en cadena: cuando la llamada en cadena, es fácil implementar la llamada en cadena en el método Evaluator (Setter) (o en los métodos que no devuelven los valores), pero el Getter de valor es relativamente difícil de implementar la llamada en cadena, porque necesita el Getter de valor para devolver los datos que necesita en lugar de este puntero. Si desea implementar el método de cadena, puede usar una función de devolución de llamada para implementarlo.
La función llama a SetTimeOut y SetInterval obtiene su valor de retorno. Dado que ambas funciones son asincrónicas, es decir, su tiempo de llamadas y el proceso principal del programa son relativamente independientes, no hay forma de esperar su valor de retorno en el cuerpo, y el programa no se detendrá y esperará cuando se abran, de lo contrario el significado de SetTimeOut y SetInterval se perderá. Por lo tanto, no tiene sentido usar retorno, por lo que la devolución de llamada solo se puede usar. El significado de la devolución de llamada es notificar la función proxy de los resultados de la ejecución del temporizador para un procesamiento oportuno.
3. Las funciones también son objetos
Si desea comprender la función de devolución de llamada, primero debe comprender claramente las reglas de la función. En JavaScript, las funciones son extrañas, pero de hecho son objetos. Para ser precisos, una función es un objeto de función creado con el constructor de function (). El objeto de función contiene una cadena que contiene el código JavaScript de la función. Si fue transferido de C o Java, esto puede parecer extraño, ¿cómo podría ser el código una cadena? Pero para JavaScript, esto es bastante común. La diferencia entre datos y código es vaga.
// La función se puede crear de esta manera var fn = nueva función ("arg1", "arg2", "return arg1 * arg2;"); fn (2, 3); // 6Una ventaja de esto es que puede aprobar código a otras funciones, o puede pasar variables u objetos regulares (porque el código es literalmente solo un objeto).
Transferir la función como devolución de llamada
Es fácil pasar una función como parámetro.
función fn (arg1, arg2, devolución de llamada) {var num = math.ceil (math.random () * (arg1 - arg2) + arg2); devolución de llamada (num); // pase el resultado} fn (10, 20, function (num) {console.log ("devolución de llamada llamada! num:" + num);}); // El resultado es un número aleatorio entre 10 y 20Tal vez hacer esto parece engorroso e incluso un poco estúpido, ¿por qué no devolver el resultado anormalmente? Pero cuando tenga que usar una función de devolución de llamada, ¡no lo piense!
No te interpongas en el camino
Las funciones tradicionales ingresan datos como parámetros y usan declaraciones de retorno para devolver los valores. En teoría, hay una declaración de retorno de retorno al final de la función, que está estructurada: un punto de entrada y un punto de salida. Esto es más fácil de entender. Las funciones están mapeando esencialmente el proceso de implementación entre la entrada y la salida.
Sin embargo, cuando el proceso de implementación de la función es muy largo, ¿debería elegir esperar a que la función complete el procesamiento o usar la función de devolución de llamada para realizar un procesamiento asíncrono? En este caso, el uso de funciones de devolución de llamada se vuelve crítica, como: solicitud AJAX. Si usa una función de devolución de llamada para el procesamiento, el código puede continuar realizando otras tareas sin vaciarla. En el desarrollo real, las llamadas asíncronas a menudo se usan en JavaScript, ¡e incluso se recomienda encarecidamente aquí!
A continuación se muestra un ejemplo más completo de la carga de archivos XML usando AJAX y usando la función Call () para llamar a la función de devolución de llamada en el contexto del objeto solicitado.
función fn (url, devolución de llamada) {var httprequest; // crear xhr httprequest = window.xmlhttprequest? nuevo xmlhttprequest (): window.activexObject? new ActiveXObject ("Microsoft.xmlhttp"): Undefined; // Detección funcional para IE httprequest.onreadyStateChange = function () {if (httprequest.readyState === 4 && httprequest.status === 200) {// statuse statuse con juicio }}; httprequest.open ("get", url); httprequest.send ();} fn ("text.xml", function () {// llame a la función console.log (this); // salida después de esta declaración}); console.log ("Esto se ejecutará antes de la devolución de llamada anterior"); // Esta declaración sale primeroNuestras solicitudes de procesamiento asincrónico significa que cuando comenzamos a solicitar, les decimos que llamen a nuestra función cuando estén terminados. En situaciones reales, el controlador de eventos OnreadyStateChange también debe considerar la falla de la solicitud. Aquí suponemos que el archivo XML existe y puede ser cargado con éxito por el navegador. En este ejemplo, la función asincrónica se asigna al evento OnReadyStateChange y, por lo tanto, no se ejecuta de inmediato.
Finalmente, la segunda declaración de consola.log se ejecuta primero, porque la función de devolución de llamada no se ejecuta hasta que se complete la solicitud.
El ejemplo anterior no es fácil de entender, así que eche un vistazo al siguiente ejemplo:
función foo () {var a = 10; Función de retorno () {a *= 2; regresar a; }; } var f = foo (); f (); // return 20.f (); // regresa 40.La función se llama externamente y aún puede acceder a la variable a. Todo esto se debe a que el alcance en JavaScript es léxico. Funcional se ejecuta en el alcance que los define (el alcance dentro de Foo en el ejemplo anterior), en lugar de en el alcance donde se ejecuta esta función. Mientras F se define en Foo, puede acceder a todas las variables definidas en Foo, incluso si la ejecución de FOO ha terminado. Debido a que su alcance se guardará, pero solo la función devuelta puede acceder al alcance guardado. Devolver una función anónima incrustada es el método más común para crear cierres.
Lo anterior se trata de este artículo, espero que sea útil para todos aprender la programación de JavaScript.