Pregunta

Yo uso jQuery. Y no quiero llamadas AJAX paralelas sobre mi solicitud, cada llamada deben esperar la previa antes de comenzar. Cómo implementarlo? No hay nadie que ayudara?

Actualizar Si hay alguna versión sincrónica del XMLHttpRequest o jQuery.post me gustaría saber. Pero secuencial! = Sincrónica, y me gustaría una solución asincrónica y secuencial.

¿Fue útil?

Solución

Hay una manera mucho mejor de hacerlo que mediante llamadas ajax síncronos. Jquery ajax devuelve un diferido por lo que sólo puede usar el encadenamiento de tubería para asegurarse de que cada llamada ajax termina antes de las próximas carreras. Aquí está un ejemplo de trabajo con una mayor profundidad en el ejemplo puede 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 ni idea de lo que hace el código. Con el fin de entenderlo, primero tiene que entender javascript promesas. Estoy bastante seguro de promesas están a punto de ser una característica del lenguaje Javascript nativo, así que debería dar un buen incentivo para aprender.

Otros consejos

Existen dos opciones que se me ocurre. Una es a ellos cadena a través de devoluciones de llamada. El otro es para hacer las llamadas síncronas en lugar de asíncrono.

¿Hay una razón por la que quiere que secuencial? Eso va a ralentizar las cosas.

Para hacer el sincrónica llamada, usted establece la opción async en la llamada Ajax en false. Consulte la documentación en http://docs.jquery.com/Ajax/jQuery.ajax#options (haga clic en las opciones de la pestaña para verlas).

Usted podría dar narrativa Javascript a intentarlo http://www.neilmix.com/narrativejs/doc /

Nunca he utilizado yo mismo sin embargo. Si quería hacer esto, lo haría algún tipo de configuración de la abstracción para encadenar acciones asíncronos. Como otros han dicho, la versión synchonous de los bloques objeto ajax eventos se procesa mientras se está a la espera de una respuesta. Esto hace que el navegador para que parezca que está congelado hasta que recieves una respuesta.

La mejor forma en que podría hacerlo es mediante el encadenamiento de las devoluciones de llamada como dijo Nosredna. Yo no recomendaría el uso de XMLHttpRequest síncrono ya que bloquean toda su aplicación.

No hay mucha ayuda para esto como lo que yo sé, pero se puede hacer algo parecido a un FIFO de devolución de llamada.

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

Pero recuerda una llamada síncrona se congelará la página hasta que se recibe la respuesta, por lo que no se puede utilizar en un centro de producción, ya que los usuarios se enfadarán si por alguna razón tienen que esperar 30 segundos con su navegador congelado.

EDIT: OK, con su actualización es más claro lo que quiere lograr;)

Por lo tanto, el código puede tener este aspecto:

    $.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 manera, sólo se emitió la segunda llamada cuando la respuesta a la primera llamada ha sido recibido y procesado, y sólo será emitido la tercera llamada cuando la respuesta a la segunda llamada se ha recibido y procesado. Este código es para getJSON pero se puede adaptar a $ .ajax.

Ajuste el asíncrono a falso, por ejemplo.,

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

Referencia: Ajax / jQuery.ajax

llamadas síncronas no son necesariamente más lento, si usted tiene una aplicación donde AJAX llama abierta, puestos a, luego se cierra un socket, varias llamadas a la toma no tiene sentido ya que algunas tomas sólo puede manejar una sola conexión, en cuyo caso, las colas de datos por lo que su única envía cuando la anterior llamada AJAX ha completado significa mucho más alto rendimiento de datos.

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

MDN

Puede utilizar promesa de hacer llamadas Ajax secuencial. Usando empuje de la matriz y método de la promesa del pop, llamadas ajax secuenciales será mucho más fácil.

var promises = [Promise.resolve()];

function methodThatReturnsAPromise(id) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: 'https://jsonplaceholder.typicode.com/todos/'+id,
      dataType:'json',
      success: function(data)
      {
        console.log("Ajax Request Id"+id);
        console.log(data);
        resolve();
      }
    });
  });
} 

function pushPromise(id)
{
  promises.push(promises.pop().then(function(){
    return methodThatReturnsAPromise(id)}));
}


pushPromise(1);
pushPromise(3);
pushPromise(2);

¿Cómo sobre el uso de eventos 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ónica, y me gustaría una solución asíncrona y secuencial

ejecución síncrona generalmente significa "usando el mismo reloj", mientras que la ejecución secuencial significa "siguiente en orden o secuencia".

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top