script how definicion defer async javascript jquery jquery-1.5 jquery-deferred

javascript - how - jquery definicion



¿Cómo usar jQuery Deferred con eventos personalizados? (2)

Tengo dos procesos abstractos (por ejemplo, administrados dentro de objetos js que usan el patrón de módulo revelador que no exponen sus elementos internos) que disparan eventos personalizados cuando se completan. Quiero realizar una acción cuando se hayan activado ambos eventos personalizados.

La nueva lógica Deferred en jQuery 1.5 parece que sería una forma ideal de gestionar esto, excepto que el método when () toma objetos diferidos que devuelven una promesa () (o objetos js normales, pero luego cuando () se completa inmediatamente en lugar de Esperando, lo cual es inútil para mi).

Idealmente me gustaría hacer algo como:

//execute when both customevent1 and customevent2 have been fired $.when(''customevent1 customevent2'').done(function(){ //do something });

¿Cuál sería la mejor manera de casarse con estas dos técnicas?


Puede tener los controladores de eventos para "customevent1" y "customevent2" cada uno de los cuales señala una instancia "Diferida" cuando se disparan. Puedes usar "$ .when ()" para combinar esos dos en uno, y ahí es donde pones el controlador para que se active solo después de que se hayan activado ambos eventos personalizados.

var df1 = $.Deferred(), df2 = $.Deferred(); $(''whatever'').bind(''customevent1'', function() { // code code code df1.resolve(); }).bind(''customevent2'', function() { // code code code df2.resolve(); }); var whenBoth = $.when(df1, df2); whenBoth.then(function() { // code to run after both "customevent1" // and "customevent2" have fired });

Vieja respuesta, aquí por el bien de la integridad.

Puede crear su propio objeto diferido que realiza un seguimiento de las dos condiciones y se dispara "resolver" cuando ambas se configuran:

function watchEvents() { var df = $.Deferred(); var flags = {}; $.each(Array.prototype.slice.call(arguments, 0), function() { flags[this] = false; }); var realResolve = df.resolve.bind(df); df.resolve = function(eventName) { flags[eventName] = true; for (var ev in flags) if (flags[ev] === false) return; realResolve(); }; return df; }

Ahora puedes llamar a esa función:

var df = watchEvents("customevent1", "customevent2");

Y ahora sus controladores de eventos para esos eventos solo necesitan llamar "resolver" esa cosa cuando detecten los eventos:

df.resolve(event.type);

Cada manejador reporta su propio tipo. Solo cuando todos los tipos de eventos solicitados cuando llamaste "watchEvents" hayan ocurrido, las funciones del controlador que registras en "df" realmente serán llamadas.

Se me ocurre que otra cosa que podrías hacer sería escribir un complemento jQuery que inicialice un objeto diferido para elementos y lo almacene en una propiedad ".data ()". Luego, podría escribir algunos complementos más que puedan usar los manejadores de eventos para señalarse a sí mismos, y otros complementos para registrar manejadores para secuencias de múltiples eventos. Eso sería bastante bueno, creo, pero necesito pasar un tiempo reflexionando sobre ello.


http://jsfiddle.net/ch47n/

Creé un pequeño complemento que crea un nuevo método jQuery.fn.when.

La sintaxis es:

jQuery( "whatever" ).when( "event1 event2..." ).done( callback );

Utiliza jQuery.when () ampliamente internamente y garantiza que todos los eventos se hayan activado en todos los elementos de la colección antes de resolverlos.

Código de complemento actual a continuación:

( function( $ ) { $.fn.when = function( events ) { var deferred, $element, elemIndex, eventIndex; // Get the list of events events = events.split( //s+/g ); // We will store one deferred per event and per element var deferreds = []; // For each element for( elemIndex = 0; elemIndex < this.length; elemIndex++ ) { $element = $( this[ elemIndex ] ); // For each event for ( eventIndex = 0; eventIndex < events.length; eventIndex++ ) { // Store a Deferred... deferreds.push(( deferred = $.Deferred() )); // ... that is resolved when the event is fired on this element $element.one( events[ eventIndex ], deferred.resolve ); } } // Return a promise resolved once all events fired on all elements return $.when.apply( null, deferreds ); }; } )( jQuery );