Supposons ensuite qu'une autre méthode JavaScript appelé myFunction
est appelée sur ma page lorsque myCallback
est appelée de façon asynchrone.
Ne une opération de l'emporter sur les autres? Faire les deux fonctionnent en même temps? Ce qui se passe?
JavaScript dans les navigateurs est monothread (sauf à l'aide de votre web des travailleurs, et la syntaxe qui est explicite). Donc, myFunction
sera exécuté jusqu'à ce qu'il retourne avec certaines mises en garde (continuer à lire). Si la couche ajax effectue une opération tout en myFunction
est en marche (ce qui peut très bien), et elle doit appeler la fonction de rappel, que l'appel est en attente. La prochaine fois que votre code rendements, l'appel suivant dans la file d'attente va être déclenchée.
Il semble, alors, que nous n'avons jamais à vous soucier des conditions de course. C'est surtout vrai, mais il y a des subtilités. Considérez par exemple ce code:
var img = document.createElement('img');
img.src = /* ...the URL of the image... */;
img.onload = function() {
// Handle the fact the image loaded
foo();
};
doSomethingElse();
doYetAnotherThing();
Depuis JavaScript dans les navigateurs est mono-thread, je suis assuré d'obtenir l' load
cas lorsque l'image est chargée, droite?
Mal.
Le JavaScript code est mono-thread, mais le reste de l'environnement n'est probablement pas. Ainsi, il peut arriver que, après avoir défini la img.src
, le navigateur peut voir qu'il a une copie en cache de l'image, on peut utiliser, et si elle déclenche le load
d'un événement sur l' img
entre l' img.src = ...
ligne et l' img.onload = ...
ligne de. Depuis mon gestionnaire n'est pas attaché, je n'ai pas l'appeler, parce que par moment j'ai joint mon gestionnaire, l'événement a déjà tiré.
Mais vous pouvez voir l'effet de la mise en attente si l'on inverse ces lignes:
var img = document.createElement('img');
img.onload = function() {
// Handle the fact the image loaded
foo();
};
img.src = /* ...the URL of the image... */;
doSomethingElse();
doYetAnotherThing();
Maintenant, je suis d'accroche de l'événement avant de paramètre src
. Si l'événement se déclenche entre l' img.src = ...
ligne et l' doSomethingElse
ligne (parce que le navigateur a l'image dans le cache), le rappel de mon handler se met en file d'attente. doSomethingElse
et doYetAnotherThing
exécuté avant mon gestionnaire. Uniquement lorsque le contrôle est passé de mon code ne la le d'attente appel à mon gestionnaire de finalement se faire rouler. Le code JavaScript est mono-thread, mais l'environnement n'est pas.
Vous pouvez également donner à l'hôte de l'environnement de manière non évidente. Par exemple, en appelant alert
ou de ses breathren confirm
, prompt
, etc. Ces fonctions tenir comme les maux de pouces, ils sont modernes JavaScript parce qu'ils ne sont pas guidés par les événements; au lieu de cela, exécution de JavaScript est suspendue pendant une fenêtre modale est affichée. Mais comme bobince points dans sa discussion en profondeur ici, cela ne signifie pas qu'aucun autre code sera exécuté alors que le modal est à l'affiche. C'est toujours mono-thread, mais le fil conducteur est suspendu dans un endroit (par le modal) et utilisé pour exécuter du code ailleurs dans le temps; une très belle distinction, en effet. (Bob aussi des points à certaines de gestion des événements — son focus
exemple — qui semble briser cette règle, mais il ne le fait pas. Son exemple les appels focus
, qui appelle à son tour les gestionnaires d'événements, puis retourne; pas différents de vous appeler vos propres fonctions.) La chose à retenir les éléments que Bob points ont en commun, c'est que votre code a appelé dans quelque chose dans l'environnement d'accueil qui ne s'en va et fait quelque chose (qui affiche une boîte de dialogue modale, les incendies blur
et focus
des gestionnaires, etc.).
(alert
et son breathren en particulier de provoquer toutes sortes de méchanceté, en particulier autour de la focus
et blur
, et je vous recommande de les éviter au profit de techniques plus modernes (qui peut aussi regarder sur 18x mieux).)
Donc, ce sont les mises en garde mentionnées au début de la réponse. Et en particulier, si l' myFunction
des appels alert
, au moins sur Firefox, l'ajax d'achèvement de rappel va se faire au cours de l' alert
(il ne sera pas sur la plupart des autres navigateurs). Si vous êtes curieux de découvrir ce qui fonctionne et ne se produit pas lors d' alerts
et autres, voici une page de test test setTimeout
et ajax; vous pouvez étendre les tests d'aller plus loin.