setTimeout comportement avec blocage de code
C'est mon code de test (violon ici):
console.log('Before wait');
setTimeout(function () { console.log('Yo!'); }, 1000);
var start = Date.now();
while (Date.now() < start + 3000) {}
console.log('After wait');
C'est la chronologie des événements dans google Chrome:
- Time de 0 secondes: Imprime "Avant d'attendre"
- De temps de 3 secondes: Imprime "Après attendre", et puis tout de suite après "Yo!"
Ce comportement est-il selon spec? Pourquoi n'est-il pas
- Time de 0 secondes: Imprime "Avant d'attendre"
- De temps de 3 secondes: Imprime "Après attendre"
- Temps 4 seoncds: Imprime "Yo!"
?
Vous devez vous connecter pour publier un commentaire.
Le retard de
setTimeout
est relative à l'exact moment où il est appelé. Il expire alors que vous êtes toujours occupé attente. Donc, il sera effectué à l'instant où le contrôle va revenir dans la boucle d'événements.Edit:
La spec est un peu vague en ce moment, mais j'imagine que c'est prévu et seulement interprétation directe:
JavaScript est mono-thread. Si certains bloc de code utilise thread d'exécution, aucun autre code peut être exécuté. Cela signifie que votre
setTimeout()
appel doit attendre d'exécution principal (celui avec occupé-attendrewhile
boucle) finitions.Voici ce qui se passe: vous planifiez
setTimeout()
à exécuter après une deuxième, puis bloquer le thread principal pendant 3 secondes. Cela signifie que le moment de votre occupé boucle se termine, le délai d'attente de 2 secondes trop tard - et JS moteur essaie de suivre en appelant votre délai d'attente dès que possible - ce qui est, immédiatement.En fait, c':
est l'une des pires choses à faire en JavaScript. Vous tenez JavaScript thread d'exécution pendant 3 secondes et aucun autre événement/de rappel peut être exécutée. Généralement les navigateurs "geler" dans cette période de temps.
Lorsque vous exécutez l'occupés à-boucle d'attente après l'appel de setTimeout, vous ne laissez pas le temps pour votre "Yo!" pour imprimer, parce que le runtime Javascript est occupé avec votre boucle (actuellement l'instruction vide rend également occupé à cause de continue evaulaation de la condition de la boucle).
Vous devriez toujours éviter une telle occupé-boucle d'attente, parce que jusqu'à ce que les finitions, rien d'autre ne peut être appelé à exécuter dans la fenêtre.