Frage

ich jQuery verwenden. Und ich will nicht parallel AJAX Anrufe auf meiner Anwendung muss jeder Aufruf die vorherige warten vor dem Start. Wie es zu implementieren? Es gibt jeden Helfer?

UPDATE Wenn es irgendeine synchrone Version des XMLHttpRequest oder jQuery.post ist, würde Ich mag wissen. Aber sequenzielle! = Synchron, und ich würde eine asynchrone und sequentielle Lösung gefällt.

War es hilfreich?

Lösung

Es gibt einen viel besseren Weg, dies zu tun, als synchrone Ajax-Aufrufe verwenden. JQuery Ajax gibt eine latente, so können Sie nur Rohrverkettungs verwenden, um sicherzustellen, dass jeder Ajax-Aufruf beendet ist, bevor die nächsten Läufe. Hier ist ein funktionierendes Beispiel mit einer mehr in die Tiefe Beispiel Sie href="http://jsfiddle.net/tchaffee/Df3ay/" mit auf jsfiddle spielen.

// 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.

            });

    });

}

Einige Leute haben gesagt, sie haben keine Ahnung, was der Code tut. Um sie zu verstehen, müssen Sie zuerst Javascript Versprechen verstehen. Ich bin ziemlich sicher, dass Versprechungen sind bald eine native JavaScript-Sprache-Funktion sein, so dass Sie sollten gibt einen guten Anreiz zu lernen.

Andere Tipps

Sie haben zwei Möglichkeiten, die ich denken kann. Man ist zu verketten sie durch Rückrufe. Die andere ist, um die Anrufe zu machen synchron statt async.

Gibt es einen Grund, warum Sie sie sequentiell wollen? Das wird die Dinge verlangsamen.

Um den Anruf synchron zu machen, werden Sie von der Asynchron-Option in dem Ajax-Aufruf auf false gesetzt. Lesen Sie die Dokumentation unter http://docs.jquery.com/Ajax/jQuery.ajax#options (klicken sie auf Optionen Registerkarte, sie zu sehen).

Sie geben könnten narrativen javascript ein Versuch http://www.neilmix.com/narrativejs/doc /

ich es nie selbst wenn verwendet haben. Wenn ich wollte, dies zu tun, würde ich Setup eine Art von Abstraktion für die Verkettung asynchrone Aktionen. Wie andere gesagt haben, verarbeitet die synchonous Version der Ajax-Objektblöcke Ereignisse aus, während sie auf eine Antwort wartet. Dies bewirkt, dass der Browser schauen, wie es gefroren ist, bis er eine Antwort recieves.

Der beste Weg, dies tun könnte, ist durch Rückrufe als Nosredna Verkettungs sagte. Ich würde mit synchronem XMLHttpRequest nicht empfehlen, wie sie Ihre gesamte Anwendung sperren.

Es gibt nicht viel Helfer für dies, soweit ich weiß, aber man könnte so etwas wie einen Rückruf FIFO tun.

Blick auf diese: http://docs.jquery.com/Ajax/jQuery.ajax (klicken Sie auf die Registerkarte "Optionen").

Aber denken Sie daran einen synchronen Aufruf wird die Seite einfrieren, bis die Antwort empfangen wird, so dass es nicht in einer Produktionsstätte verwendet werden können, da die Benutzer verrückt werden, wenn aus irgendeinem Grund, den sie 30 Sekunden lang mit ihrem Browser eingefroren warten müssen.

EDIT: ok, mit dem Update ist es klarer, was Sie erreichen wollen;)

So, Ihr Code wie folgt aussehen:

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

Auf diese Weise wird der zweite Anruf nur dann ausgegeben werden, wenn die Reaktion auf den ersten Anruf empfangen wurde und verarbeitet werden, und der dritte Anruf wird nur dann erteilt werden, wenn die Antwort auf den zweiten Anruf empfangen wurde und verarbeitet. Dieser Code ist für getJSON aber es kann zu .ajax $ angepasst werden.

Stellen Sie die async Option auf false, z. B.

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

Referenz: Ajax / jQuery.ajax

Synchron Anrufe sind nicht unbedingt langsamer, wenn Sie eine App haben, wo AJAX-Aufrufe geöffnet, Beiträge, schließt sich dann eine Buchse, mehrere Anrufe an die Buchse keinen Sinn machen, da einige Steckdosen nur eine einzige Verbindung verarbeiten kann, in wobei dann Warteschlangendaten so sein nur gesendet, wenn der vorherige AJAX Anruf beendet hat, bedeutet viel höheren Datendurchsatz.

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. fordert 3 JSON-Dateien mit jQuery Ajax-Aufrufen
  2. Prozess nacheinander (nicht parallel) mit Await
  3. funktioniert in Chrome / Firefox / Edge (Stand: 2018.01.30)

mehr unter MDN

Sie können die Versprechen verwenden, um Ajax-Aufrufe sequentielle zu machen. Mit Array Push- und Pop-Versprechen Methode, sequenzielle Ajax-Aufrufe wird viel einfacher.

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

Wie wäre es mit Node.js Ereignisse?

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

sequenziellen! = Synchron, und ich würde eine asynchrone mögen und sequentielle Lösung

Synchrone Ausführungs Allgemeinen bedeutet „der gleiche Takt verwendet“, während die sequentielle Ausführung bedeutet „in folgenden Reihenfolge oder Sequenz“.

Für Ihren spezifischen Anwendungsfall denke ich, dass beide Bedingungen erfüllt sein müssen, als die asynchrone Ausführung die Möglichkeit eines nicht-sequenziellen Ergebnis impliziert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top