Domanda

Io uso jQuery. E non voglio che le chiamate AJAX parallele su mia domanda, ogni chiamata devono attendere il precedente prima di iniziare. Come per la sua attuazione? Non v'è alcun aiuto?

Aggiorna Se non v'è alcuna versione sincrona del XMLHttpRequest o jQuery.post vorrei sapere. Ma sequenziale! = Sincrona, e vorrei una soluzione asincrono e sequenziale.

È stato utile?

Soluzione

C'è un modo molto migliore per farlo che utilizzando chiamate Ajax sincrone. Jquery ajax restituisce una differita in modo da poter utilizzare solo il tubo concatenamento per fare in modo che ogni chiamata AJAX termina prima delle prossime corse. Ecco un esempio di lavoro con una più approfondita esempio puoi giocare con il 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.

            });

    });

}

Alcune persone hanno commentato non hanno idea di cosa fa il codice. Per capirlo, è necessario innanzitutto capire javascript promesse. Sono abbastanza sicuro che le promesse stanno per essere una caratteristica del linguaggio JavaScript nativo, in modo che dovrebbe dare un buon incentivo per imparare.

Altri suggerimenti

Hai due scelte che mi viene in mente. Uno è a loro catena attraverso i callback. L'altra è per effettuare le chiamate sincrone piuttosto che asincrona.

C'è un motivo che si desidera loro sequenziali? Che rallentare le cose.

Per rendere la sincrona chiamata, si imposta l'opzione async nella chiamata Ajax per falso. Vedere la documentazione a http://docs.jquery.com/Ajax/jQuery.ajax#options (fare clic su opzioni scheda per vederli).

Si potrebbe dare narrativa javascript un http://www.neilmix.com/narrativejs/doc /

Non ho mai usato da solo però. Se avessi voluto fare questo, vorrei messa a punto una sorta di astrazione per il concatenamento azioni asincrone. Come altri hanno già detto, la versione synchonous dei blocchi oggetto ajax eventi di essere elaborati mentre sta aspettando una risposta. Questo fa sì che il browser a guardare come è congelato fino a quando non riceve una risposta.

Il modo migliore che si possa fare questo è il concatenamento callback come diceva Nosredna. Non suggerirei usando XMLHttpRequest sincrono in quanto bloccano l'intera applicazione.

Non ci sono molto aiuto per questo per quanto ne so, ma si potrebbe fare qualcosa di simile a un FIFO di callback.

Guardate questa: http://docs.jquery.com/Ajax/jQuery.ajax (clicca sulla scheda "opzioni").

Ma ricordate una chiamata sincrona si blocca la pagina fino a quando viene ricevuta la risposta, quindi non può essere utilizzato in un sito di produzione, perché gli utenti si arrabbierà se per qualsiasi motivo devono aspettare 30 secondi con il loro browser congelati.

EDIT: ok, con l'aggiornamento è più chiaro ciò che si vuole raggiungere;)

Quindi, il codice può assomigliare a questo:

    $.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);
            });
        });
    });

In questo modo, la seconda chiamata verrà emesso solo quando la risposta alla prima chiamata è stato ricevuto ed elaborato, e la terza chiamata verrà emesso solo quando la risposta alla seconda chiamata è stato ricevuto ed elaborato. Questo codice è per getJSON ma può essere adattato a $ .ajax.

Imposta asincrona per falso, per es.,

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

Riferimento: Ajax / jQuery.ajax

chiamate sincroni non sono necessariamente più lenta, se si dispone di un'applicazione in cui chiamate AJAX aperto, posti a, quindi chiude un socket, chiamate multiple alla presa non hanno senso come alcune prese possono gestire solo una singola connessione, in qual caso, accodamento dati così suo inviato solo quando il precedente chiamata AJAX ha completato significa throughput molto più elevato.

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. richiede 3 file JSON con chiamate Ajax jQuery
  2. processo in sequenza (non in parallelo) con await
  3. funziona in Chrome / Firefox / Edge (come del 2018/01/30)

MDN

È possibile utilizzare promessa di fare chiamate AJAX sequenziale. Che utilizza la matrice spinta e metodo di promessa pop, chiamate ajax sequenziali sarà molto più facile.

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);

Come sull'utilizzo di eventi 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);
  

sequenziale! = Sincrona, e desidero asincrono e sequenziale soluzione

esecuzione sincrona generalmente significa "utilizzando lo stesso clock", mentre l'esecuzione sequenziale significa "segue in ordine o sequenza".

Per caso uso specifico ritengo entrambe le condizioni devono essere soddisfatte, come esecuzione asincrona implica la possibilità di un risultato non sequenziale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top