Le seul problème avec les promesses est que IE ne les prend pas en charge. Edge le fait, mais il y a beaucoup d'IE 10 et 11 là-bas: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise (compatibilité en bas)
Donc, JavaScript est monothread. Si vous n'effectuez pas d'appel asynchrone, il se comportera de manière prévisible. Le thread JavaScript principal exécutera une fonction complètement avant d'exécuter la suivante, dans l'ordre dans lequel elles apparaissent dans le code. Garantir l'ordre des fonctions synchrones est trivial - chaque fonction s'exécutera complètement dans l'ordre dans lequel elle a été appelée.
Considérez la fonction synchrone comme une unité atomique de travail . Le thread JavaScript principal l'exécutera entièrement, dans l'ordre dans lequel les instructions apparaissent dans le code.
Mais, lancez l'appel asynchrone, comme dans la situation suivante:
showLoadingDiv(); // function 1
makeAjaxCall(); // function 2 - contains async ajax call
hideLoadingDiv(); // function 3
Cela ne fait pas ce que vous voulez . Il exécute instantanément la fonction 1, la fonction 2 et la fonction 3. Le chargement de div clignote et il est parti, alors que l'appel ajax n'est pas presque terminé, même s'il makeAjaxCall()
est retourné. LA COMPLICATION est qu'il makeAjaxCall()
a brisé son travail en morceaux qui sont avancés petit à petit à chaque rotation du thread JavaScript principal - il se comporte de manière asychronique. Mais ce même thread principal, pendant un spin / run, a exécuté les parties synchrones rapidement et de manière prévisible.
Donc, la façon dont je l'ai géré : comme je l'ai dit, la fonction est l'unité atomique de travail. J'ai combiné le code de la fonction 1 et 2 - J'ai mis le code de la fonction 1 dans la fonction 2, avant l'appel asynchrone. Je me suis débarrassé de la fonction 1. Tout jusqu'à et y compris l'appel asynchrone s'exécute de manière prévisible, dans l'ordre.
ALORS, lorsque l'appel asynchrone se termine, après plusieurs tours du thread JavaScript principal, faites-lui appeler la fonction 3. Cela garantit l'ordre . Par exemple, avec ajax, le gestionnaire d'événements onreadystatechange est appelé plusieurs fois. Lorsqu'il signale qu'il est terminé, appelez la fonction finale souhaitée.
Je suis d'accord que c'est plus compliqué. J'aime que le code soit symétrique, j'aime que les fonctions fassent une chose (ou s'en rapprochent), et je n'aime pas que l'appel ajax soit en aucune façon responsable de l'affichage (créant une dépendance sur l'appelant). MAIS, avec un appel asynchrone incorporé dans une fonction synchrone, des compromis doivent être faits pour garantir l'ordre d'exécution. Et je dois coder pour IE 10 donc pas de promesses.
Résumé : Pour les appels synchrones, garantir l'ordre est trivial. Chaque fonction s'exécute entièrement dans l'ordre dans lequel elle a été appelée. Pour une fonction avec un appel asynchrone, le seul moyen de garantir l'ordre est de surveiller la fin de l'appel asynchrone et d'appeler la troisième fonction lorsque cet état est détecté.
Pour une discussion sur les fils JavaScript, voir: https://medium.com/@francesco_rizzi/javascript-main-thread-dissected-43c85fce7e23 et https://developer.mozilla.org/en-US/docs/Web/JavaScript/ EventLoop
Aussi, une autre question similaire et très appréciée à ce sujet: comment appeler 3 fonctions pour les exécuter l'une après l'autre?
firstFunction
ce que fait exactement qui le rend asynchrone? De toute façon - Vérifiez les promesses