Estoy usando jQuery.queue() por primera vez y no lo he entendido del todo. ¿Podría alguien señalar qué estoy haciendo mal?
Mirando en Firebug, todavía veo que mis solicitudes POST se activan al mismo tiempo, por lo que me pregunto si estoy llamando a dequeue () en el lugar equivocado.
Además, ¿cómo puedo obtener la longitud de la cola?
La razón por la que necesito poner en cola estas solicitudes es que se activa al hacer clic en un botón. Y es posible que el usuario haga clic en varios botones en rápida sucesión.
Intenté eliminar la estructura básica de mi código:
$("a.button").click(function(){ $(this).doAjax(params); }); // method doAjax:function(params){ $(document).queue("myQueueName", function(){ $.ajax({ type: 'POST', url: 'whatever.html', params: params, success: function(data){ doStuff; $(document).dequeue("myQueueName"); } }); }); }
Su problema aquí es que .ajax()
dispara una solicitud Ajax de ejecución asíncrona. Eso significa que .ajax()
regresa inmediatamente, sin bloqueo. Entonces, ponga en cola las funciones, pero se activarán casi al mismo tiempo como lo describió.
No creo que .queue()
sea un buen lugar para tener solicitudes ajax, está más destinado al uso de fx methods
. Necesitas un administrador simple.
var ajaxManager = (function() { var requests = []; return { addReq: function(opt) { requests.push(opt); }, removeReq: function(opt) { if( $.inArray(opt, requests) > -1 ) requests.splice($.inArray(opt, requests), 1); }, run: function() { var self = this, oriSuc; if( requests.length ) { oriSuc = requests[0].complete; requests[0].complete = function() { if( typeof(oriSuc) === 'function' ) oriSuc(); requests.shift(); self.run.apply(self, []); }; $.ajax(requests[0]); } else { self.tid = setTimeout(function() { self.run.apply(self, []); }, 1000); } }, stop: function() { requests = []; clearTimeout(this.tid); } }; }());
Esto está lejos de ser perfecto, solo quiero demostrar el camino a seguir. El ejemplo anterior podría usarse de una manera como
$(function() { ajaxManager.run(); $("a.button").click(function(){ ajaxManager.addReq({ type: 'POST', url: 'whatever.html', data: params, success: function(data){ // do stuff } }); }); });
Necesitaba hacer algo similar, así que pensé en publicar mi solución aquí.
Básicamente, lo que tengo es una página que enumera proyectos en estantes que tienen criterios distintivos. Quería cargar los estantes uno por uno en lugar de todos juntos para que el usuario pudiera ver contenido más rápido mientras se carga el resto.
Básicamente almacené la ID de cada estante en una matriz JS que uso cuando los llamo desde PHP.
Luego creé una función recursiva que sacará el primer índice de la matriz cada vez que se llame y solicite el estante para la identificación emergente. Una vez que tengo la respuesta de $.get()
o $.post()
, cualquiera que prefiera usar, llamo a la función recursiva desde dentro de la devolución de llamada.
Aquí hay una elaboración en código:
// array of shelf IDs var shelves = new Array(1,2,3,4); // the recursive function function getShelfRecursive() { // terminate if array exhausted if (shelves.length === 0) return; // pop top value var id = shelves[0]; shelves.shift(); // ajax request $.get('/get/shelf/' + id, function(){ // call completed - so start next request getShelfRecursive(); }); } // fires off the first call getShelfRecursive();
Utilizo este código muy simple para evitar que las llamadas ajax se "superen" entre sí.
var dopostqueue = $({}); function doPost(string, callback) { dopostqueue.queue(function() { $.ajax( { type: 'POST', url: 'thephpfile.php', datatype: 'json', data: string, success:function(result) { dopostqueue.dequeue(); callback(JSON.parse(result)); } }) }); }
Si no desea que la cola se maneje sola, simplemente puede quitar la dequeue
de la función y llamarla desde otra función. En cuanto a obtener la longitud de la cola, para este ejemplo sería:
dopostqueue.queue().length