jQuery 1.5 trae el nuevo objeto diferido y los métodos adjuntos .when
, .Deferred
y ._Deferred
.
Para aquellos que no han usado .Deferred
antes, he anotado la fuente para ello .
¿Cuáles son los posibles usos de estos nuevos métodos, cómo hacemos para adaptarlos a los patrones?
Ya he leído la API y la fuente , así que sé lo que hace. Mi pregunta es ¿cómo podemos usar estas nuevas funciones en el código cotidiano?
Tengo un ejemplo simple de una clase de búfer que llama a la solicitud AJAX en orden. (El siguiente comienza después del anterior).
/* Class: Buffer
* methods: append
*
* Constructor: takes a function which will be the task handler to be called
*
* .append appends a task to the buffer. Buffer will only call a task when the
* previous task has finished
*/
var Buffer = function(handler) {
var tasks = [];
// empty resolved deferred object
var deferred = $.when();
// handle the next object
function handleNextTask() {
// if the current deferred task has resolved and there are more tasks
if (deferred.isResolved() && tasks.length > 0) {
// grab a task
var task = tasks.shift();
// set the deferred to be deferred returned from the handler
deferred = handler(task);
// if its not a deferred object then set it to be an empty deferred object
if (!(deferred && deferred.promise)) {
deferred = $.when();
}
// if we have tasks left then handle the next one when the current one
// is done.
if (tasks.length > 0) {
deferred.done(handleNextTask);
}
}
}
// appends a task.
this.append = function(task) {
// add to the array
tasks.push(task);
// handle the next task
handleNextTask();
};
};
Estoy buscando demostraciones y posibles usos de .Deferred
y .when
.
También sería encantador ver ejemplos de ._Deferred
.
Vinculación a lo nuevo jQuery.ajax
fuente de ejemplos es hacer trampa.
Estoy particularmente interesado en las técnicas disponibles cuando abstraemos si una operación se realiza de forma sincrónica o asincrónica.
fuente
._Deferred
es simplemente el verdadero "objeto diferido" que.Deferred
utiliza. Es un objeto interno que probablemente nunca necesitarás.Respuestas:
El mejor caso de uso que se me ocurre es el almacenamiento en caché de las respuestas AJAX. Aquí hay un ejemplo modificado de la publicación de introducción de Rebecca Murphey sobre el tema :
Básicamente, si el valor ya se solicitó una vez antes, se devuelve inmediatamente desde la memoria caché. De lo contrario, una solicitud AJAX obtiene los datos y los agrega a la memoria caché. Al
$.when
/.then
no le importa nada de esto; todo lo que debe preocuparle es usar la respuesta, que se pasa al.then()
controlador en ambos casos.jQuery.when()
maneja un No Prometido / Diferido como Completado, ejecutando inmediatamente cualquiera.done()
o.then()
en la cadena.Los diferidos son perfectos para cuando la tarea puede o no funcionar de forma asincrónica, y desea abstraer esa condición del código.
Otro ejemplo del mundo real usando el
$.when
ayudante:fuente
cache[ val ]
devuelve una promesa (la documentación de jquery dice que el parámetro son los datos devueltos por el remitente) lo que significa que el acceso de miembros de.then
will error ... ¿verdad? ¿Qué me estoy perdiendo?Aquí hay una implementación ligeramente diferente de un caché AJAX como en la respuesta de ehynd .
Como se señaló en la pregunta de seguimiento de fortuneRice, la implementación de ehynd en realidad no evitó múltiples solicitudes idénticas si las solicitudes se realizaron antes de que uno de ellos regresara. Es decir,
probablemente dará como resultado 3 solicitudes AJAX si el resultado de "xxx" no se ha almacenado en caché antes.
Esto se puede resolver almacenando en caché los aplazamientos de la solicitud en lugar del resultado:
fuente
Se puede usar un diferido en lugar de un mutex. Esto es esencialmente lo mismo que los múltiples escenarios de uso de ajax.
MUTEX
DIFERIDO
Cuando utilice un diferido solo como mutex, tenga cuidado con los impactos en el rendimiento (http://jsperf.com/deferred-vs-mutex/2). Aunque la conveniencia, así como los beneficios adicionales proporcionados por un diferido bien valen la pena, y en el uso real (basado en eventos impulsados por el usuario), el impacto en el rendimiento no debería ser notable.
fuente
Esta es una respuesta autopromocional, pero pasé unos meses investigando esto y presenté los resultados en jQuery Conference San Francisco 2012.
Aquí hay un video gratuito de la charla:
https://www.youtube.com/watch?v=juRtEEsHI9E
fuente
Otro uso que he estado haciendo con un buen propósito es obtener datos de múltiples fuentes. En el ejemplo a continuación, busco varios objetos de esquema JSON independientes utilizados en una aplicación existente para la validación entre un cliente y un servidor REST. En este caso, no quiero que la aplicación del lado del navegador comience a cargar datos antes de que se hayan cargado todos los esquemas. $ .when.apply (). then () es perfecto para esto. Gracias a Raynos por los indicadores sobre el uso de entonces (fn1, fn2) para monitorear las condiciones de error.
fuente
Otro ejemplo que usa
Deferred
s para implementar un caché para cualquier tipo de cómputo (generalmente algunas tareas de alto rendimiento o de ejecución prolongada):Aquí hay un ejemplo del uso de esta clase para realizar algunos cálculos (pesados simulados):
El mismo caché subyacente podría usarse para almacenar en caché las solicitudes de Ajax:
Puedes jugar con el código anterior en este jsFiddle .
fuente
1) Úselo para garantizar una ejecución ordenada de devoluciones de llamada:
2) Úselo para verificar el estado de la aplicación:
fuente
Puede usar un objeto diferido para hacer un diseño fluido que funcione bien en los navegadores webkit. Los navegadores de Webkit activarán el evento de cambio de tamaño para cada píxel de la ventana, a diferencia de FF e IE, que activan el evento solo una vez para cada cambio de tamaño. Como resultado, no tiene control sobre el orden en que se ejecutarán las funciones vinculadas a su evento de cambio de tamaño de ventana. Algo como esto resuelve el problema:
Esto serializará la ejecución de su código para que se ejecute como lo desea. Tenga cuidado con las trampas al pasar métodos de objeto como devoluciones de llamada a un diferido. Una vez que dicho método se ejecuta como una devolución de llamada diferida, la referencia 'this' se sobrescribirá con referencia al objeto diferido y ya no se referirá al objeto al que pertenece el método.
fuente
resizeQueue.done(resizeAlgorithm)
es exactamente lo mismo queresizeAlgorithm
. Es una farsa completa!.done
.También puede integrarlo con cualquier biblioteca de terceros que utilice JQuery.
Una de esas bibliotecas es Backbone, que en realidad admitirá Diferido en su próxima versión.
fuente
read more here
en lugar deon my blog
. Es una mejor práctica y puede salvar su respuesta de (accidentalmente) ser spam. :)Acabo de usar diferido en código real. En el proyecto jQuery Terminal, tengo una función ejecutiva que llama a comandos definidos por el usuario (como si la estuviera ingresando y presionando enter), agregué aplazamientos a la API y llamé a la ejecutiva con matrices. Me gusta esto:
o
los comandos pueden ejecutar código asíncrono, y el ejecutivo necesita llamar al código de usuario en orden. Mi primera API utiliza un par de llamadas de pausa / reanudar y en una nueva API las llamo automáticamente cuando el usuario promete. Entonces el código de usuario solo puede usar
o
Yo uso un código como este:
dalyed_commands se utiliza en la función de reanudación que llama a exec nuevamente con todos los dalyed_commands.
y parte de la función de comandos (he eliminado partes no relacionadas)
fuente
La respuesta de ehynds no funcionará porque almacena en caché los datos de las respuestas. Debe almacenar en caché el jqXHR, que también es una promesa. Aquí está el código correcto:
La respuesta de Julian D. funcionará correctamente y es una mejor solución.
fuente