web-dev-qa-db-fra.com

Existe-t-il un moyen d'attendre la réponse AJAX et d'arrêter l'exécution?

Voici du code que j'aimerais exécuter. Je voudrais attendre la réponse AJAX pour que je puisse retourner quelque chose du serveur. Quel moyen d'y parvenir?

function functABC(){
    $.ajax({
        url: 'myPage.php',
        data: {id: id},
        success: function(data) {
            return data;
        }
    });

    //Wait for AJAX (???)
}

var response = functABC();
36
OneMore

Tous les appels Ajax peuvent être effectués soit de manière asynchrone (avec une fonction de rappel, ce serait la fonction spécifiée après la touche "succès"), soit de manière synchrone - bloquant et attendant efficacement la réponse des serveurs. Pour obtenir une exécution synchrone, vous devez spécifier

async: false 

comme décrit ici

Notez, cependant, que dans la plupart des cas, une exécution asynchrone (via un rappel en cas de succès) est très bien.

29
Alexander Presber

La réponse simple est de désactiver async. Mais ce n'est pas la bonne chose à faire. La bonne réponse est de repenser la façon dont vous écrivez le reste de votre code.

Au lieu d'écrire ceci:

function functABC(){
    $.ajax({
        url: 'myPage.php',
        data: {id: id},
        success: function(data) {
            return data;
        }
    });
}

function foo () {
    var response = functABC();
    some_result = bar(response);
    // and other stuff and
    return some_result;
}

Vous devriez l'écrire comme ceci:

function functABC(callback){
    $.ajax({
        url: 'myPage.php',
        data: {id: id},
        success: callback
    });
}

function foo (callback) {
    functABC(function(data){
        var response = data;
        some_result = bar(response);
        // and other stuff and
        callback(some_result);
    })
}

Autrement dit, au lieu de renvoyer le résultat, passez le code de ce qui doit être fait en tant que rappels. Comme je l'ai montré, les rappels peuvent être imbriqués à autant de niveaux que vous avez d'appels de fonction.


ne explication rapide de la raison pour laquelle je dis qu'il est incorrect de désactiver l'async:

La désactivation de l'async gèlera le navigateur en attendant l'appel ajax. L'utilisateur ne peut pas cliquer sur quoi que ce soit, ne peut pas faire défiler et dans le pire des cas, si l'utilisateur manque de mémoire, parfois lorsque l'utilisateur fait glisser la fenêtre hors de l'écran et la fait glisser à nouveau, il verra des espaces vides parce que le navigateur est gelé et ne peut pas redessiner. Pour les navigateurs à thread unique comme IE7, c'est encore pire: tous les sites Web se bloquent! Les utilisateurs qui rencontrent cela peuvent penser que votre site est bogué. Si vous ne voulez vraiment pas le faire de manière asynchrone, effectuez simplement votre traitement à l'arrière-plan et actualisez la page entière. Il ne se sentirait au moins pas buggé.

20
slebetman

Si vous pouvez utiliser des promesses, vous pouvez également utiliser une chaîne de promesses.

function functABC() {
  return new Promise(function(resolve, reject) {
    $.ajax({
      url: 'myPage.php',
      data: {id: id},
      success: function(data) {
        resolve(data) // Resolve promise and go to then()
      },
      error: function(err) {
        reject(err) // Reject the promise and go to catch()
      }
    })
  }
}

functABC().then(function(data) {
  // Run this when your request was successful
  console.log(data)
}).catch(function(err) {
  // Run this when promise was rejected via reject()
  console.log(err)
})
13
dome2k

Il n'est pas nécessaire d'attendre une réponse Ajax. Vous pouvez charger vos données dans la section tête de votre application:

function functABC(){
    $.ajax({
        url: 'myPage.php',
        data: {id: id},
        success: function(data) {
            sessionStorage.setItem('mydata', data);
        }
    });
} 

Ensuite, lorsque l'événement window.load s'est déclenché, vos données seront disponibles:

alert(sessionStorage.getItem('mydata'));
0
johannes