105 votes

Comment faire attendre le code lors d'appels asynchrones comme Ajax ?

Je cherche quelque chose comme ceci

function someFunc() {

callAjaxfunc(); //may have multiple ajax calls in this function
someWait(); // some code which waits until async calls complete
console.log('Pass2');

}

function callAjaxfunc() {
  //All ajax calls called here
  console.log('Pass1');

}

Ce que j'ai essayé ?

1 Jquery.when()

J'ai essayé de l'utiliser. Il fonctionne bien. Mais pas comme je le souhaite. $.when attendra mais le code à côté de $.when() fonctionne sans attendre. Le code à l'intérieur do callback ne fonctionne qu'après des appels ajax

2. setTimeOut() avec un drapeau global

J'étais tellement sûr que ça allait marcher. J'ai essayé ce qui suit.

GlobalFlag = false;

function someFunc()     
    callAjaxfunc(); //may have multiple ajax calls in this function
    setTimeOut(waitFunc, 100); // some  which waits until async calls complete
    console.log('Pass2');
}

function callAjaxfunc() {
    //All ajax calls called here
    onAjaxSuccess: function() {
        GlobalFlag = true;
    };
    console.log('Pass1');    
}

function waitFunc() {
    if (!GlobalFlag) {
        setTimeOut(waitFunc, 100);
    }
}

Je n'arrive toujours pas à obtenir le résultat souhaité. Est-ce que je fais quelque chose de mal ici ? Ce n'est pas la bonne méthode ?

Le résultat que je voulais devrait venir comme ceci

Pass1
Pass2

Impossible de faire des manipulations car cela nécessite des appels AJAX.

EDIT : Comme beaucoup ont suggéré des callbacks je les connais mais quand même le code à côté de somewait() sera exécuté...Je veux que le navigateur arrête complètement d'exécuter le code à côté de somewait() jusqu'à l'appel ajax... Aussi, cela peut être une mauvaise pratique mais cela vaut la peine de savoir et d'essayer si possible...

61voto

Dogbert Points 44003

Utilisez des rappels. Quelque chose comme ceci devrait fonctionner sur la base de votre exemple de code.

function someFunc() {

callAjaxfunc(function() {
    console.log('Pass2');
});

}

function callAjaxfunc(callback) {
    //All ajax calls called here
    onAjaxSuccess: function() {
        callback();
    };
    console.log('Pass1');    
}

Ceci imprimera Pass1 immédiatement (en supposant que la requête ajax prend au moins quelques microsecondes), puis imprimez Pass2 lorsque le onAjaxSuccess est exécuté.

20voto

Alexander Points 13227

Pourquoi cela n'a pas fonctionné pour vous en utilisant Deferred Objects ? A moins que j'aie mal compris quelque chose, cela pourrait vous convenir.

/* AJAX success handler */
var echo = function() {
    console.log('Pass1');
};

var pass = function() {
  $.when(
    /* AJAX requests */
    $.post("/echo/json/", { delay: 1 }, echo),
    $.post("/echo/json/", { delay: 2 }, echo),
    $.post("/echo/json/", { delay: 3 }, echo)
  ).then(function() {
    /* Run after all AJAX */
    console.log('Pass2');
  });
};​

Voir ici .


UPDATE

D'après vos informations, il semble que l'alternative la plus rapide soit d'utiliser des requêtes synchrones. Vous pouvez définir la propriété async a false dans votre $.ajax des demandes pour les rendre bloquantes. Cependant, cela bloquera votre navigateur jusqu'à ce que la requête soit terminée.

Remarquez que je ne recommande pas cela et que je considère toujours que vous devriez fixer votre code dans un flux de travail basé sur les événements pour ne pas en dépendre.

8voto

Amadan Points 41944

Les vrais programmeurs le font avec des sémaphores.

Avoir une variable définie comme 0 . Incrémentez-le avant chaque appel AJAX. Décrémentez-le dans chaque gestionnaire de succès, et testez pour les éléments suivants 0 . Si c'est le cas, vous avez terminé.

0voto

HMarioD Points 516

Si vous devez attendre que l'appel ajax soit terminé, il vous suffit de faire votre appel de manière synchrone.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X