¿Cómo hacer todas las llamadas AJAX secuenciales?

Yo uso jQuery. Y no quiero llamadas AJAX paralelas en mi aplicación, cada llamada debe esperar la anterior antes de comenzar. ¿Cómo implementarlo? Hay algún ayudante?

ACTUALIZACIÓN Si hay alguna versión síncrona de XMLHttpRequest o jQuery.post me gustaría saber. Pero secuencial! = Sincrónico, y me gustaría una solución asíncrona y secuencial.

Hay una manera mucho mejor de hacer esto que usar llamadas ajax sincrónicas. Jquery ajax devuelve un diferido por lo que puede utilizar el encadenamiento de tuberías para asegurarse de que cada llamada ajax finaliza antes de las siguientes ejecuciones. Aquí hay un ejemplo de trabajo con un ejemplo más en profundidad con el que puedes jugar en jsfiddle .

// How to force async functions to execute sequentially // by using deferred pipe chaining. // The master deferred. var dfd = $.Deferred(), // Master deferred dfdNext = dfd; // Next deferred in the chain x = 0, // Loop index values = [], // Simulates $.ajax, but with predictable behaviour. // You only need to understand that higher 'value' param // will finish earlier. simulateAjax = function (value) { var dfdAjax = $.Deferred(); setTimeout( function () { dfdAjax.resolve(value); }, 1000 - (value * 100) ); return dfdAjax.promise(); }, // This would be a user function that makes an ajax request. // In normal code you'd be using $.ajax instead of simulateAjax. requestAjax = function (value) { return simulateAjax(value); }; // Start the pipe chain. You should be able to do // this anywhere in the program, even // at the end,and it should still give the same results. dfd.resolve(); // Deferred pipe chaining. // What you want to note here is that an new // ajax call will not start until the previous // ajax call is completely finished. for (x = 1; x <= 4; x++) { values.push(x); dfdNext = dfdNext.pipe(function () { var value = values.shift(); return requestAjax(value). done(function(response) { // Process the response here. }); }); } 

Algunas personas han comentado que no tienen idea de lo que hace el código. Para entenderlo, primero necesita comprender las promesas javascript. Estoy bastante seguro de que pronto las promesas serán una característica nativa del lenguaje javascript, por lo que debería darle un buen incentivo para aprender.

Tienes dos opciones que puedo pensar. Una es encadenarlos a través de devoluciones de llamadas. La otra es hacer que las llamadas sean sincrónicas en lugar de asincrónicas.

¿Hay alguna razón por la que quiera que sean secuenciales? Eso ralentizará las cosas.

Para que la llamada sea sincrónica, configurará la opción asincrónica en la llamada Ajax como falsa. Consulte la documentación en http://docs.jquery.com/Ajax/jQuery.ajax#options (haga clic en la pestaña de opciones para verlas).

Establezca la opción asíncrona en falso, por ejemplo,

 $.ajax({ async: false /*, your_other_ajax_options_here */ }); 

Referencia: Ajax / jQuery.ajax

Podría dar un javascript narrativo try http://www.neilmix.com/narrativejs/doc/

Aunque nunca lo he usado yo mismo. Si quisiera hacer esto, configuraría algún tipo de abstracción para encadenar acciones asíncronas. Como han dicho otros, la versión sincrónica del objeto ajax impide que los eventos se procesen mientras espera una respuesta. Esto hace que el navegador parezca estar congelado hasta que reciba una respuesta.

La mejor manera de hacerlo es encadenando devoluciones de llamada como dijo Nosredna. No recomendaría usar XMLHttpRequest sincrónico ya que bloquean toda la aplicación.

No hay mucha ayuda para esto hasta donde yo sé, pero podrías hacer algo parecido a un FIFO de callback.

Mira esto: http://docs.jquery.com/Ajax/jQuery.ajax ( haz clic en la pestaña “opciones”).

Pero recuerde que una llamada síncrona congelará la página hasta que se reciba la respuesta, por lo que no se podrá usar en un sitio de producción, porque los usuarios se enojarán si por alguna razón tienen que esperar 30 segundos con el navegador congelado.

EDIT: ok, con tu actualización está más claro lo que quieres lograr;)

Por lo tanto, su código puede verse así:

  $.getJSON("http://example.com/jsoncall", function(data) { process(data); $.getJSON("http://example.com/jsoncall2", function (data) { processAgain(data); $.getJSON("http://example.com/anotherjsoncall", function(data) { processAgainAndAgain(data); }); }); }); 

De esta forma, la segunda llamada solo se emitirá cuando se haya recibido y procesado la respuesta a la primera llamada, y la tercera solo se emitirá cuando se haya recibido y procesado la respuesta a la segunda llamada. Este código es para getJSON pero se puede adaptar a $ .ajax.

Las llamadas síncronas no son necesariamente más lentas, si tiene una aplicación donde se abren las llamadas AJAX, se envía a las publicaciones y luego cierra un socket, las múltiples llamadas al socket no tienen sentido ya que algunos sockets solo pueden manejar una sola conexión, en cuyo caso poner en cola los datos por lo que solo se envía cuando la llamada AJAX anterior se ha completado significa un rendimiento de datos mucho más alto.

 (async () => { for(f of ['1.json','2.json','3.json']){ var json = await $.getJSON(f); console.log(json) }; })() 
  1. solicita 3 archivos json con llamadas jQuery ajax
  2. proceso en secuencia (no en paralelo) con espera
  3. funciona en Chrome / Firefox / Edge (desde 1/30/2018)

más en MDN

¿Qué tal si usamos los eventos de Node.js?

 var EventEmitter = require('events').EventEmitter; var eventEmitter = new EventEmitter(); var $ = require('jquery'); var doSomething = function (responseData) { var nextRequestData = {}; // do something with responseData return nextRequestData; }; // ajax requests var request1 = $.ajax; var request2 = $.ajax; var requests = [request1, request2]; eventEmitter.on('next', function (i, requestData) { requests[i](requestData).then( function (responseData) { console.log(i, 'request completed'); if (i+1 < requests.length) { var nextRequestData = doSomething(responseData); eventEmitter.emit('next', i+1, nextRequestData); } else { console.log('completed all requests'); } }, function () { console.log(i, 'request failed'); } ); }); var data = { //data to send with request 1 }; eventEmitter.emit('next', 0, data); 

secuencial! = sincrónico, y me gustaría una solución asíncrona y secuencial

La ejecución síncrona generalmente significa “usar el mismo reloj”, mientras que la ejecución secuencial significa “seguir en orden o secuencia”.

Para su caso de uso específico, creo que se deben cumplir ambas condiciones, ya que la ejecución asincrónica implica la posibilidad de un resultado no secuencial.