JQuery: attendez-vous que la fonction soit terminée pour continuer le traitement?

Salut à tous. J'ai, ce qui semble être, un problème trivial. J'ai le JavaScript suivant:

$(function() { var r = GetResults(); for(var i = 0; i < r.length; i++) { // Do stuff with r } }); function GetResults() { $.getJSON("/controller/method/", null, function(data) { return data; }); } 

En raison du fait que j'appelle une méthode de manière asynchrone, le script continue d'être exécuté et quand il rencontre la boucle for, r ne va évidemment pas encore avoir de valeur. Ma question est la suivante: quand j'ai une méthode qui effectue une opération asynchrone, et je dépend des données renvoyées dans le bloc principal, comment puis-je arrêter l'exécution jusqu'à ce que les données soient retournées? Quelque chose comme:

 var r = GetResults(param, function() { }); 

Où la fonction est une fonction de rappel. Je ne peux pas déplacer le traitement de la boucle pour la fonction de rappel de la requête JSON car je réutilise la fonctionnalité de GetResults plusieurs fois dans toute la page, sauf si je veux dupliquer le code. Des idées?

Déplacez votre bloc «faire du truc avec r» dans votre rappel de $ .getJSON. Vous ne pouvez pas faire de choses avec r jusqu'à ce qu'il ait été livré, et la première opportunité que vous devrez utiliser r est dans le rappel … alors, faites-le alors.

 $(function() { var r = GetResults(); }); function GetResults() { $.getJSON("/controller/method/", null, function(data) { for(var i = 0; i < data.length; i++) { // Do stuff with data } return data; }); } 

Ajax vous appelle déjà un rappel, vous êtes censé l'utiliser:

 function dostuff( data ) { for(var i = 0; i < data.length; i++) { // Do stuff with data } }; $(document).ready( function() { $.getJSON( "/controller/method/", null, dostuff ); }); 

J'ai rencontré quelque chose de semblable auparavant. Vous devrez exécuter l'appel ajax de manière synchrone.

Voici mon exemple de travail:

 $.ajax({ type: "POST", url: "/services/GetResources", contentType: "application/json; charset=utf-8", dataType: "json", data: '{resourceFileName:"mapedit",culture:"' + $("#lang-name").val() + '"}', cache: true, async: false, // to set local variable success: function(data) { localizations = data.d; } }); 

Vous pourriez faire ceci:

 $(function() { PerformCall(); }); function PerformCall() { $.getJSON("/controller/method/", null, function(data) { for(var i = 0; i < data.length; i++) { // Do stuff with data } }); } 

La réponse courte est que vous ne pouvez pas bloquer sur une opération asynchrone … ce qui est évidemment la signification de "asynchrone".

Au lieu de cela, vous devez modifier votre code pour utiliser un rappel pour déclencher l'action en fonction des données renvoyées par l' $.getJSON(...) . Quelque chose comme le suivant devrait fonctionner:

 $(function() { GetResults(); }); function GetResults() { $.getJSON("/controller/method/", null, function(data) { for(var i = 0; i < data.length; i++) { // Do stuff with data } }); } 

Compte tenu de vos exigences mises à jour …

Je ne peux pas déplacer le traitement de la boucle pour la fonction de rappel de la requête JSON car je réutilise la fonctionnalité de GetResults plusieurs fois dans toute la page, sauf si je veux dupliquer le code. Des idées?

… vous pouvez modifier GetResults() pour accepter une fonction en tant que paramètre, que vous exécuteriez alors comme $.getJSON (avertissement de code d'air):

 $(function() { GetResults(function(data) { for(var i = 0; i < data.length; i++) { // Do stuff with data } }); }); function GetResults(callback) { $.getJSON("/controller/method/", null, callback); } 

Comme vous pouvez le voir à partir de la marge générale de réponses, vous n'êtes pas obligé de lutter contre le modèle de programmation asynchrone jQuery. 🙂

Ce n'est pas possible.

Soit vous rendez votre fonction synchrone, soit vous modifiez la conception de votre code pour prendre en charge l'opération asynchrone.

Vous pouvez avoir un rappel avec des paramètres qui devraient bien fonctionner …

 $(function() { GetResults(function(data) { for(var i = 0; i < data.length; i++) { // Do stuff with data } }); }); function GetResults(func) { $.getJSON("/controller/method/", null, func); } 

Déplacez le traitement des données dans le rappel:

 $(function() { GetResults(); }); function GetResults() { $.getJSON("/controller/method/", null, function(data) { for(var i = 0; i < data.length; i++) { // Do stuff with data } }); }