jQuery: retour des données après le succès de l'appel ajax [dupliquer]

cette question a déjà une réponse ici:

  • Comment retourner la réponse d'un appel asynchrone? 33 réponses

j'ai quelque chose comme ça, où c'est un simple appel à un script qui me redonne une valeur, une chaîne de caractères..

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {
         return data; 
      }
   });
}

mais si je l'appelle quelque chose comme ceci

var output = testAjax(svar);  // output will be undefined...

alors, comment puis-je retourner la valeur? le code ci-dessous ne semble pas fonctionner non plus...

function testAjax() {
    $.ajax({
      url: "getvalue.php",  
      success: function(data) {

      }
   });
   return data; 
}
396
demandé sur Hakam Fostok 2011-03-15 22:08:26

5 réponses

La seule manière de renvoyer les données à partir de la fonction serait de faire un appel synchrone au lieu d'un appel asynchrone, mais qui aurait pour effet de geler le navigateur tandis qu'il attend la réponse.

, Vous pouvez passer d'une fonction de rappel qui gère le résultat:

function testAjax(handleData) {
  $.ajax({
    url:"getvalue.php",  
    success:function(data) {
      handleData(data); 
    }
  });
}

l'Appeler comme ceci:

testAjax(function(output){
  // here you use the output
});
// Note: the call won't wait for the result,
// so it will continue with the code here while waiting.
335
répondu Guffa 2011-03-15 19:13:39

Note: Cette réponse a été écrite en février 2010.

voir les mises à jour de 2015, 2016 et 2017 en bas.

vous ne pouvez rien tirer d'une fonction asynchrone. Ce que vous pouvez retourner est un promesse . J'ai expliqué comment les promesses fonctionnent à jQuery dans mes réponses à ces questions:

Si vous pouviez expliquer pourquoi voulez-vous retourner les données et ce que vous voulez faire avec elle plus tard, alors je pourrais être en mesure de vous donner plus de réponse précise comment le faire.

en général, au lieu de:

function testAjax() {
  $.ajax({
    url: "getvalue.php",  
    success: function(data) {
      return data; 
    }
  });
}

vous pouvez écrire votre fonction testamax comme ceci:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

, Alors vous pouvez obtenir votre promesse comme ceci:

var promise = testAjax();

vous pouvez stocker votre promesse, vous pouvez la transmettre, vous pouvez l'utiliser comme argument dans les appels de fonction et vous pouvez la retourner à partir des fonctions, mais quand vous voulez enfin utiliser vos données qui est retourné par L'appel AJAX, vous devez le faire comme ceci:

promise.success(function (data) {
  alert(data);
});

(Voir les mises à jour ci-dessous pour vous simplifier la syntaxe.)

Si vos données sont disponibles à ce point, alors cette fonction sera appelé immédiatement. Si ce n'est pas le cas, alors elle sera invoquée dès que les données sont disponibles.

Le but de tout cela est que vos données ne sont pas disponibles immédiatement après l'appel de $.ajax, car il est asynchrone. Promesses est une belle abstraction pour les fonctions de dire: je ne peux pas vous retourner le données parce que je ne l'ai pas encore et je ne veux pas bloquer et vous faire attendre donc voici un promesse à la place et vous serez en mesure de l'utiliser plus tard, ou de simplement le donner à quelqu'un d'autre et être fait avec elle.

voir ce DEMO .

UPDATE (2015)

actuellement (mars 2015) les promesses de jQuery ne sont pas compatibles avec les promesses de / a+ spécification qui signifie qu'ils peuvent ne pas coopérer très bien avec d'autres promesses/a+ implémentations conformes .

Toutefois jQuery Promesses dans la prochaine version 3.x sera être compatible avec les Promesses que/Un+ spécification (merci à Benjamin Gruenbaum pour le pointage). Actuellement (mai 2015) les versions stables de jQuery sont 1.x et 2.x.

ce que j'ai expliqué ci-dessus (en mars 2011) est une façon d'utiliser jQuery objets différés pour faire quelque chose de façon asynchrone que dans le code synchrone serait atteint en retournant une valeur.

mais un appel de fonction synchrone peut faire deux choses - il peut retourner une valeur (si elle peut) ou jeter une exception (si elle ne peut pas retourner une valeur). Promises / a + s'adresse à ces deux cas d'utilisation d'une manière à peu près aussi puissante que l'exception manipulation en code synchrone. La version jQuery traite l'équivalent de retourner une valeur juste fine, mais l'équivalent d'une manipulation d'exception complexe est quelque peu problématique.

en particulier, le point entier du traitement d'exception en code synchrone n'est pas simplement d'abandonner avec un beau message, mais d'essayer de corriger le problème et de continuer l'exécution, ou éventuellement de repenser la même ou une exception différente pour certaines autres parties du programme à gérer. Dans synchrone le code que vous avez une pile d'appel. Dans les appels asynchrones, vous ne le faites pas et la gestion des exceptions avancées à l'intérieur de vos promesses comme l'exige la spécification Promises/a+ peut vraiment vous aider à écrire du code qui traitera les erreurs et les exceptions de manière significative, même pour les cas d'utilisation complexes.

Pour les différences entre jQuery et d'autres implémentations, et comment convertir jQuery promesses Promesses/A+ conforme, voir jQuery par Kris Kowal et coll. sur le wiki de la bibliothèque Q et les promesses arrivent en JavaScript par Jake Archibald sur les rochers HTML5.

comment rendre une vraie promesse

la fonction de mon exemple ci-dessus:

function testAjax() {
  return $.ajax({
      url: "getvalue.php"
  });
}

renvoie un objet jqXHR, qui est un jQuery objet différé .

pour le faire revenir une promesse réelle, vous pouvez le changer en-utilisant la méthode de le wiki Q :

function testAjax() {
  return Q($.ajax({
      url: "getvalue.php"
  }));
}

ou, à l'aide de la méthode de l'HTML5 Rocks article :

function testAjax() {
  return Promise.resolve($.ajax({
      url: "getvalue.php"
  }));
}

Ce Promise.resolve($.ajax(...)) est aussi ce qui est , a expliqué dans le promise documentation du module et il devrait travailler avec les ES6 Promise.resolve() .

pour utiliser les promesses ES6 aujourd'hui, vous pouvez utiliser ES6-module de promesse polyfill() de Jake Archibald.

pour voir où vous pouvez utiliser les promesses ES6 sans le polyfill, voir: puis-je utiliser: promesses .

pour plus d'informations voir:

avenir de jQuery

futures versions de jQuery (à partir de 3.x-les versions stables actuelles en date de mai 2015 sont 1.x et 2.x) sera compatible avec le Promises / a+ specification (merci à Benjamin Gruenbaum pour l'avoir souligné dans les commentaires). " deux changements que nous avons déjà décidé sont promesse/a+ Compatibilité pour notre mise en œuvre différée [...]" ( jQuery 3.0 et l'avenir du développement Web ). Pour plus d'informations, voir: jQuery 3.0: Les Prochaines Générations par Dave Methvin et jQuery 3.0: Plus d'interopérabilité, moins D'Internet Explorer par Paul Krill.

des discussions Intéressantes

mise à JOUR (2016)

il existe une nouvelle syntaxe dans ECMA-262, 6e édition, Section 14.2 appelée fonctions de flèche qui peut être utilisée pour simplifier davantage les exemples ci-dessus.

utilisant L'API jQuery, au lieu de:

promise.success(function (data) {
  alert(data);
});

vous pouvez écrire:

promise.success(data => alert(data));

ou en utilisant L'API promesses/a+ :

promise.then(data => alert(data));

N'oubliez pas d'utiliser toujours des manipulateurs de rejet avec:

promise.then(data => alert(data), error => alert(error));

ou avec:

promise.then(data => alert(data)).catch(error => alert(error));

voyez cette réponse pour voir pourquoi vous devriez toujours utiliser des gestionnaires de refus avec des promesses:

bien sûr, dans cet exemple, vous pourriez utilisez juste promise.then(alert) parce que vous appelez juste alert avec les mêmes arguments que votre callback, mais la syntaxe de flèche est plus générale et vous permet d'écrire des choses comme:

promise.then(data => alert("x is " + data.x));

tous les navigateurs ne supportent pas encore cette syntaxe, mais il y a certains cas où vous êtes sûr du navigateur sur lequel votre code sera lancé - par exemple, lors de l'écriture d'un Chrome extension , un Firefox Add-on , ou une application de bureau en utilisant Electron, NW.js ou AppJS (voir cette réponse pour plus de détails).

pour le support des fonctions de flèche, voir:

mise à JOUR (2017)

Il ya un encore plus récent syntaxe maintenant appelée fonctions async avec un nouveau mot-clé await qu'à la place de ce code:

functionReturningPromise()
    .then(data => console.log('Data:', data))
    .catch(error => console.log('Error:', error));

permet d'écrire:

try {
    let data = await functionReturningPromise();
    console.log('Data:', data);
} catch (error) {
    console.log('Error:', error);
}

Vous ne pouvez l'utiliser à l'intérieur d'une fonction créée avec le async mot-clé. Pour plus d'informations, voir:

pour la prise en charge dans les navigateurs, voir:

pour le support dans le noeud, voir:

dans les endroits où vous n'avez pas de support natif pour async et await vous pouvez utiliser Babel:

ou avec une syntaxe légèrement différente une approche basée sur un générateur comme dans co ou coroutines Bluebird:

plus d'information

quelques autres questions sur les promesses pour plus de détails:

361
répondu rsp 2017-05-23 11:47:25

vous pouvez ajouter l'option async au retour false et en dehors de l'appel ajax.

function testAjax() {
    var result="";
    $.ajax({
      url:"getvalue.php",
      async: false,  
      success:function(data) {
         result = data; 
      }
   });
   return result;
}
161
répondu Ging3r 2014-03-10 07:40:03

Idk si vous avez résolu les gars mais je recommande une autre façon de le faire, et il fonctionne:)

    ServiceUtil = ig.Class.extend({
        base_url : 'someurl',

        sendRequest: function(request)
        {
            var url = this.base_url + request;
            var requestVar = new XMLHttpRequest();
            dataGet = false;

            $.ajax({
                url: url,
                async: false,
                type: "get",
                success: function(data){
                    ServiceUtil.objDataReturned = data;
                }
            });
            return ServiceUtil.objDataReturned;                
        }
    })

donc l'idée principale ici est que, en ajoutant async: false, alors vous faites tout attend jusqu'à ce que les données soient récupérées. Puis vous l'assignez à une variable statique de la classe, et tout fonctionne magiquement:)

-1
répondu user1509803 2013-03-01 08:30:33

Voir exemple jquery docs: http://api.jquery.com/jQuery.ajax / (environ 2/3 la page)

vous pouvez être à la recherche du code suivant:

    $.ajax({
     url: 'ajax/test.html',
     success: function(data) {
     $('.result').html(data);
     alert('Load was performed.');
   }
});

même page...plus bas.

-11
répondu Techism 2013-07-22 10:11:40