Entiendo la idea de una devolución de llamada, donde paso una función a otra función y esa función luego usa la función suministrada a voluntad.
Me cuesta entender las devoluciones de llamada diferidas, incluso después de buscarlo en Google.
¿Podría alguien dar una explicación simple por favor? Programo en Ruby, pero también conozco un poco C / C ++, pero sobre todo era un programador experimentado en lenguaje ensamblador. Entonces, me pregunto si es un poco como una pila de direcciones de devolución de llamada que aparecen. Espero aprender jquery o node.js y estas devoluciones de llamada diferidas parecen integrales para ambos. Entiendo los principios básicos de enhebrado (aunque el objeto mutex me duele la cabeza;)
Deferred
objetos de jQuery ? ¿Se trata de algo específico de Node.js?Respuestas:
A pedido, aquí hay comentarios presentados como respuesta:
No estoy seguro de que comprenda por completo el hecho de que las funciones en JS son objetos de primera clase y, por lo tanto, pueden almacenarse hasta que se necesiten, más allá del tiempo en que se crean.
Por ejemplo, digamos que desea escribir en un archivo, luego imprima un mensaje de registro; entonces llama a la función "write ()" (o lo que sea) y le pasa una función que emite el mensaje de registro (esta es la función de devolución de llamada diferida). "write ()" almacena internamente una referencia a la función dada, comienza a escribir en el archivo y configura su propia devolución de llamada para saber cuándo finaliza la escritura. Luego regresa antes de terminar la escritura; cuando es así, la devolución de llamada interna se llama de alguna manera (este es el trabajo del marco subyacente, en el caso de node.js, se realiza con un bucle de eventos), que luego llama a su devolución de llamada que imprime el mensaje de registro.
La parte "diferida" simplemente significa que su función de devolución de llamada no se llama de inmediato; llamarlo se difiere hasta el momento apropiado. En el caso de funciones asincrónicas como muchas de las de node.js, la devolución de llamada dada generalmente se llama cuando se completa la operación (o se produce un error).
La mayoría de las cosas son asíncronas en node.js, pero en el navegador con, por ejemplo, jQuery, la mayoría de las cosas son realmente sincrónicas (excepto, obviamente, para solicitudes AJAX). Dado que las funciones de primera clase son muy útiles en JavaScript (especialmente debido al excelente soporte de cierre), las devoluciones de llamada también se usan en todas partes en el navegador, pero no se "difieren" para operaciones síncronas (excepto en la medida en que no son llamadas inmediatamente por usted, pero luego por la función que llama).
El hecho de que el sistema subyacente esté controlado por eventos es ortogonal al uso de devoluciones de llamada diferidas; puede imaginar una versión (muy lenta) de node.js que inició un hilo para cada operación, y luego llamó a su devolución de llamada dada cuando el hilo terminó su trabajo, sin usar eventos en absoluto. Por supuesto, este es un modelo horrible, pero ilustra mi punto :-)
fuente
La forma en que funciona una devolución de llamada diferida es cada vez que le agrega una devolución de llamada, esa devolución de llamada se empuja a una matriz. Luego, cuando se llama al método
.resolve()
o.resolveWith()
en el objeto diferido, todas las.done()
devoluciones de llamada en la matriz se ejecutan en orden.Ahora podemos ver qué es un objeto diferido. Tome el fragmento a continuación como ejemplo.
Lo que tenemos ahora es un objeto diferido, y el objeto prometido del objeto diferido. El objeto Diferido tiene todos los mismos métodos que el objeto promesa, sin embargo el objeto promesa solamente tiene los métodos
.done()
,.fail()
y.always()
que se utilizan para añadir devoluciones de llamada al objeto diferido para cada respectivoevent
. El objeto diferido por otro lado tiene varios otros métodos, lo más importante.resolve()
y.reject()
. Cuando se invocan estos métodos en el objeto diferido, se invocan todas las devoluciones de llamada..resolve()
activa las devoluciones de llamada.done()
y.always()
mientras que el.reject()
método llama.fail()
y.always()
devuelve llamadas.En general, el objeto diferido se mantiene oculto dentro de un ámbito privado, y el objeto de promesa se devuelve desde la función para que se puedan colocar devoluciones de llamada. El objeto diferido se resolverá más tarde, como después de que se complete una solicitud ajax o después de cargar una imagen, después de un setTimeout, etc. También es importante darse cuenta de que un objeto diferido solo se puede resolver una vez. Si ya está resuelto, sus devoluciones de llamada se llamarán de inmediato.
Aquí hay otro ejemplo, uno que yo uso:
Para obtener más información sobre el
$.Deferred()
método de jQuery y los objetos diferidos, visite http://api.jquery.com/category/deferred-object/fuente
No estoy seguro, pero creo que una devolución de llamada diferida se refiere a una devolución de llamada asincrónica, por lo que tendrá más suerte googleando para eso.
La mejor explicación que encontré fue en http://www.nodebeginner.org
En este ejemplo, probablementeExpensiveFunction es una función no bloqueante (o asíncrona). Esto significa que no se ejecuta de inmediato, sino que se coloca en un llamado bucle de eventos. El hilo de node.js continuará la ejecución, pero en algún momento decidirá ejecutar algo del bucle de eventos. Cuando llega a probablementeExpensiveFunction, lo llama, y cuando probablementeExpensiveFunction finaliza la ejecución, llama a la devolución de llamada (diferida) que se le pasa como parámetro.
Como un ejemplo de probablementeExpensiveFunction puede tomar fs.readFile
fuente
.resolve()
o.reject()
en el objeto diferido original, se llama a la lista de devoluciones de llamada.JavaScript es de un solo subproceso, por lo que no puede pensar en términos de subprocesos para comprender esto. Aquí hay un ejemplo de devoluciones de llamada regulares y asíncronas usando jQuery:
fuente
Las devoluciones de llamada diferidas (también conocidas como Promesas ) le permiten escribir código asincrónico secuencial, sin dolor y espagueti de devolución de llamada:
'when' le permite esperar a que las funciones regresen en paralelo, y
then
puede encadenarse secuencialmente.una nota: jQuery diferido ! = Promesas / A , su sintaxis es un poco diferente.
Hay buenos artículos sobre el tema: uno en IEBlog y otro en algún blog aleatorio , un libro y una pregunta popular de stackoverflow
fuente