Comment voulez-vous faire un code javascript à exécuter *afin*
Ok, donc j'apprécie que Javascript n'est pas C# ou PHP, mais je reviens pour un problème en Javascript - pas avec JS lui-même, mais mon usage.
J'ai une fonction:
function updateStatuses(){
showLoader() //show the 'loader.gif' in the UI
updateStatus('cron1'); //performs an ajax request to get the status of something
updateStatus('cron2');
updateStatus('cron3');
updateStatus('cronEmail');
updateStatus('cronHourly');
updateStatus('cronDaily');
hideLoader(); //hide the 'loader.gif' in the UI
}
Chose est, en raison de Javascript brûlante du désir de sauter de l'avant dans le code, le chargeur n'apparaît jamais, parce que le " hideLoader la fonction s'exécute tout de suite après.
Comment puis-je résoudre ce problème? Ou en d'autres termes, comment puis-je faire une fonction javascript s'exécutent dans l'ordre je l'écris sur la page...
- La Promesse est le meilleur objet pour gérer toutes les demandes asynchrones. réparer les demandes asynchrones avec la Promesse d'objet
Vous devez vous connecter pour publier un commentaire.
Le problème se produit parce que l'AJAX est dans sa nature asynchronus. Cela signifie que le
updateStatus()
appelle, en effet, sont exécutées dans l'ordre, mais retourne immédiatement et la JS interprète atteinthideLoader()
avant tout les données sont récupérées à partir de la requête AJAX.Vous devez effectuer les
hideLoader()
sur un événement où les appels AJAX sont finis.Vous devez penser à du JavaScript, basée sur les événements plutôt que de procédure si tu fais de la programmation AJAX. Vous devez attendre jusqu'à ce que le premier appel se termine avant l'exécution de la deuxième. La façon de le faire est de lier la deuxième appel à un rappel qui se déclenche lorsque le premier est terminé. Sans en savoir plus sur le fonctionnement interne de votre bibliothèque AJAX (j'espère que vous êtes en utilisant une bibliothèque) je ne peux pas vous dire comment faire cela, mais il ne sera probablement ressembler à quelque chose comme ceci:
L'idée est,
updateStatus
prend sa normal argument, en plus d'une fonction de callback à exécuter quand il est terminé. C'est un raisonnablement modèle commun pour passer d'une fonction à exécuteronComplete
dans une fonction qui offre un crochet.Mise à jour
Si vous utilisez jQuery, vous pouvez lire sur
$.ajax()
ici: http://api.jquery.com/jQuery.ajax/Votre code ressemble probablement à quelque chose comme ceci:
Vous pouvez modifier vos fonctions pour prendre un rappel comme deuxième paramètre avec quelque chose comme ceci:
}
Je pense à tout ce que vous devez faire est de les avoir dans votre code:
De sorte que votre appel Ajax devrait ressembler à ceci:
De toute évidence, certains de ce besoin de changement pour
XML
,JSON
, etc, mais laasync: false,
est le point principal ici qui racontent la JS moteur à attendre jusqu'à ce que la réussite d'appel ont retourné (ou d'échec selon le cas), et puis continuer.Rappelez-vous il ya un inconvénient à cela, et c'est que l'ensemble de la page ne répond plus jusqu'à ce que l'ajax est de retour!!! généralement dans les millisecondes, ce qui n'est pas un big deal mais POURRAIT prendre plus de temps.
Espère que c'est la bonne réponse et il vous aide à vous 🙂
Nous avons quelque chose de semblable dans l'un de nos projets, et nous l'avons résolu en utilisant un compteur. Si vous augmentez le compteur pour chaque appel à
updateStatus
et diminue dans la requête AJAX est la fonction de réponse (dépend de l'AJAX JavaScript bibliothèque que vous utilisez.)Une fois que le compteur atteint zéro, toutes les requêtes AJAX sont terminées et vous pouvez appeler
hideLoader()
.Voici un échantillon:
loadCounter < 0
cas à provoquer une erreur, car si cela arrive jamais, c'est un bug.Cela n'a rien à voir avec l'ordre d'exécution du code.
La raison que l'image de chargement ne se montre jamais, c'est que l'INTERFACE utilisateur n'est pas à jour lors de votre fonction est en cours d'exécution. Si vous faites des changements dans l'INTERFACE utilisateur, ils n'apparaissent pas jusqu'à la sortie de la fonction et revenir au navigateur.
Vous pouvez utiliser un délai d'attente après la définition de l'image, donnant le navigateur est une chance de mettre à jour l'INTERFACE utilisateur avant de commencer le reste du code:
Il y a un autre facteur qui peut également rendre votre code apparaissent à l'exécution de l'ordre. Si vos requêtes AJAX sont asynchrones, la fonction n'auront pas à attendre pour les réponses. La fonction qui se charge de la réponse à exécuter lorsque le navigateur reçoit la réponse. Si vous souhaitez masquer l'image de chargement après la réponse a été reçu, vous devez faire lors de la dernière réponse de la fonction de gestionnaire de pistes. Que les réponses n'ont pas d'arriver dans l'ordre que vous avez envoyé la demande, vous devez compter le nombre de réponses que vous avez appris à connaître lors de la dernière vient.
Comme d'autres l'ont souligné, vous ne voulez pas faire une opération synchrone. Embrasser Asynchrone, c'est ce que l'Un en AJAX signifie.
Je voudrais juste mentionner une excellente analogie sur sync v/s asynchrone. Vous pouvez lire les ensemble de poster sur le forum GWT, je suis juste y compris les analogies.
Mais, vous dites que vous voulez synchrone? Imaginez encore ...
C'est exactement ce qui se passe quand vous insistez sur le fait de faire un synchrone d'appel de serveur.
Installer Firebug, puis ajouter une ligne de ce genre pour chacun des showLoader, updateStatus et hideLoader:
Vous verrez répertoriés dans la fenêtre de la console, les appels à votre fonction, et ils seront dans l'ordre. La question, est-ce que votre "updateStatus" méthode de faire?
Vraisemblablement, il démarre une tâche en arrière-plan, puis revient, de sorte que vous arriverez à l'appel à hideLoader avant tout des tâches en arrière-plan de la finition. Votre bibliothèque Ajax a probablement une "OnComplete" ou "OnFinished" rappel - appel suivants updateStatus à partir de là.
déplacer le updateStatus appels à une autre fonction. faire un appel setTimeout avec la nouvelle fonction en tant que cible.
si vos requêtes ajax sont asynchrones, vous devriez avoir quelque chose à suivre ceux qui ont terminé. chaque méthode de rappel peut définir un "terminé" drapeau quelque part pour lui-même, et de vérifier pour voir si elle est la dernière à le faire. si elle l'est, puis de l'appel hideLoader.
L'une des meilleures solutions pour le traitement de toutes les demandes asynchrones est le "Promesse".
La Promesse de l'objet représente la réalisation éventuelle (ou l'échec) d'une opération asynchrone.
Exemple:
Promesse
Si vous avez 3 async fonctions et s'attendre à exécuter dans l'ordre, procédez comme suit:
Avec cette approche, vous pouvez gérer toutes les opération asynchrone comme vous le souhaitez.