Question

J'utilise jQuery. Et je ne veux pas les appels parallèles AJAX sur ma demande, chaque appel doit attendre la précédente avant de commencer. Comment mettre en œuvre? Il y a une aide?

UPDATE S'il existe une version synchrone du XMLHttpRequest ou jQuery.post je voudrais savoir. Mais séquentiel! = Synchrone, et je voudrais une solution asynchrone et séquentielle.

Était-ce utile?

La solution

Il y a une meilleure façon de le faire que d'utiliser les appels synchrones ajax. Jquery ajax renvoie un différé de sorte que vous pouvez simplement utiliser Enchaînement de tuyau pour vous assurer que chaque appel ajax se termine avant les prochaines courses. Voici un exemple de travailler avec un plus dans l'exemple de la profondeur, vous pouvez jouer avec le 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.

            });

    });

}

Certaines personnes ont fait des commentaires qu'ils ont aucune idée de ce que le code ne. Pour le comprendre, vous devez d'abord comprendre javascript promesses. Je suis assez sûr promesses vont bientôt être une caractéristique de langue javascript natif, ce qui devrait vous donner une bonne incitation à apprendre.

Autres conseils

Vous avez deux choix que je peux penser. La première consiste à les enchaîner par callbacks. L'autre est de faire les appels synchrones plutôt que async.

Y at-il une raison que vous voulez les séquentiels? Cela va ralentir les choses.

Pour la synchronisation d'appel, vous définissez l'option async dans l'appel Ajax false. Consultez la documentation http://docs.jquery.com/Ajax/jQuery.ajax#options (cliquez sur l'onglet options pour les voir).

Vous pouvez donner récit javascript essayer http://www.neilmix.com/narrativejs/doc /

Je ne l'ai jamais utilisé moi-même si. Si je voulais faire, je voudrais configurer une sorte d'abstraction pour chaîner actions asynchrones. Comme d'autres l'ont dit, la version synchonous des blocs d'objets ajax événements de cours de traitement pendant qu'il attend une réponse. Cela provoque le navigateur pour ressembler il est gelé jusqu'à ce qu'il reçoit une réponse.

La meilleure façon que vous pouvez faire est en enchaînant les callbacks comme dit Nosredna. Je recommande de ne pas utiliser XMLHttpRequest synchrone car ils bloquent toute votre application.

Il n'y a pas beaucoup aide pour cela comme autant que je sache, mais vous pouvez faire quelque chose qui ressemble à une FIFO de rappel.

Regardez ceci: http://docs.jquery.com/Ajax/jQuery.ajax (cliquez sur l'onglet "Options").

Mais rappelez-vous un appel synchrone va geler la page jusqu'à ce que la réponse est reçue, il ne peut pas être utilisé dans un site de production, parce que les utilisateurs vont se fâcher si pour une raison quelconque, ils doivent attendre 30 secondes avec leur navigateur gelé.

EDIT: ok, avec votre mise à jour, il est plus clair ce que vous voulez atteindre;)

Alors, votre code peut ressembler à ceci:

    $.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 cette façon, ne sera publié le deuxième appel lorsque la réponse au premier appel a été reçu et traité, et le troisième appel ne sera émis quand a été reçu la réponse au deuxième appel et traité. Ce code est pour getJSON mais il peut être adapté à .ajax $.

Régler la async false, par exemple.

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

Référence: Ajax / jQuery.ajax

appels synchrones ne sont pas forcément plus lent, si vous avez une application où AJAX appels d'offres ouverts, les messages à, puis ferme une prise, plusieurs appels à la prise ne font pas de sens que certaines prises ne peuvent gérer une seule connexion, en auquel cas, les données en file d'attente de sorte que son envoyé uniquement lorsque l'appel AJAX précédent a terminé signifie beaucoup plus un débit de données.

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. demande 3 fichiers JSON avec jQuery appels ajax
  2. processus en séquence (non en parallèle) avec await
  3. travaille dans Chrome / Firefox / bord (au 30/01/2018)

MDN

Vous pouvez utiliser la promesse de faire ajax appels séquentielle. Utilisation de Push Array et la méthode de promesse pop, les appels ajax séquentiels sera beaucoup plus 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);

Comment l'utilisation des événements 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);
  

séquentielle! = Synchrone, et je voudrais une solution asynchrone et séquentielle

exécution synchrone signifie généralement « en utilisant la même horloge », tandis que l'exécution séquentielle signifie « selon l'ordre ou la séquence ».

Pour votre cas d'utilisation spécifique, je pense que les deux conditions doivent être remplies, comme l'exécution asynchrone implique la possibilité d'un résultat non séquentielle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top