JavaScript: variables globales après requêtes Ajax

La question est assez simple et technique:

var it_works = false; $.post("some_file.php", '', function(data) { it_works = true; }); alert(it_works); # false (yes, that 'alert' has to be here and not inside $.post itself) 

Ce que je veux atteindre est:

 alert(it_works); # true 

Y-a-t-il un moyen de faire ça? Sinon, $.post() renvoie une valeur à appliquer à it_works ?

Ce que vous attendez, c'est la demande de type synchrone ( bloquant ).

 var it_works = false; jQuery.ajax({ type: "POST", url: 'some_file.php', success: function (data) { it_works = true; }, async: false // <- this turns it into synchronous });​ // Execution is BLOCKED until request finishes. // it_works is available alert(it_works); 

Les demandes sont asynchrones ( non bloquantes ) par défaut, ce qui signifie que le navigateur n'attendra pas qu'elles soient complétées afin de poursuivre leur travail. C'est pourquoi votre alerte a eu un mauvais résultat.

Maintenant, avec jQuery.ajax vous pouvez éventuellement configurer la demande comme étant synchrone , ce qui signifie que le script ne fonctionnera que si la demande est terminée.


La manière RECOMMANDÉE , cependant, est de refactoriser votre code afin que les données soient transmises à une fonction de rappel dès que la demande est terminée. Ceci est préférable parce que l'exécution de blocage signifie bloquer l'interface utilisateur qui est inacceptable. Faites-le de cette façon:

 $.post("some_file.php", '', function(data) { iDependOnMyParameter(data); }); function iDependOnMyParameter(param) { // You should do your work here that depends on the result of the request! alert(param) } // All code here should be INDEPENDENT of the result of your AJAX request // ... 

La programmation asynchrone est légèrement plus compliquée car la conséquence d'une demande est encapsulée dans une fonction au lieu de suivre l'instruction de demande. Mais le comportement en temps réel que l' utilisateur connaît peut être considérablement amélioré car il ne verra pas un serveur lent ou un réseau lent provoquant l'apparition du navigateur comme s'il s'était écrasé. La programmation synchrone est irrespectueuse et ne devrait pas être utilisée dans les applications utilisées par les personnes.

Douglas Crockford ( Blog YUI )

Il semble que votre problème soit simplement un problème de concurrence. La fonction de publication prend un argument de rappel pour vous indiquer quand la publication a été terminée. Vous ne pouvez pas faire l'alerte dans une portée globale comme celle-ci et vous attendez à ce que la publication soit déjà terminée. Vous devez le déplacer vers la fonction de rappel.

AJAX signifie JavaScript asynchrone et XML. Ainsi, la publication sur le serveur est hors-synchro avec le reste de la fonction. Essayez un code comme celui-ci (il brise le raccourci $.post dans l'appel $.ajax plus $.ajax et ajoute l'option async ).

 var it_works = false; $.ajax({ type: 'POST', async: false, url: "some_file.php", data: "", success: function() {it_works = true;} }); alert(it_works); 

J'espère que cela t'aides!

La raison pour laquelle votre code échoue est parce que post() démarrera une demande asynchrone sur le serveur. Ce que cela signifie pour vous, c'est que post() retourne immédiatement, et non après la fin de la demande, comme vous l'attendez.

Ce dont vous avez besoin, c'est que la demande soit synchrone et bloquez le fil actuel jusqu'à ce que la demande soit terminée. Ainsi,

 var it_works = false; $.ajax({ url: 'some_file.php', async: false, # makes request synchronous success: function() { it_works = true; } }); alert(it_works);