En JavaScript, setTimeout(callback, delay)
signifie "appeler callback
après delay
millisecondes". Mais que faire si delay
est 0
? Doit-il appeler immédiatement callback
?
Je suis confus à cause de ce que je vois lorsque j'exécute le code suivant:
setTimeout(function() {
console.log('AAA');
}, 0); // Call this in 0 milliseconds
for (i = 0; i < 1000; i++) {
console.log('BBB');
}
for (i = 0; i < 1000; i++) {
console.log('CCC');
}
for (i = 0; i < 1000; i++) {
console.log('DDD');
}
for (i = 0; i < 1000; i++) {
console.log('EEE');
}
Cela enregistre les éléments suivants dans la console:
Je m'attendais à voir AAA
connecté beaucoup plus tôt que cela. Il était temps d'exécuter 4000 autres appels à console.log
devant une fonction qui aurait dû être appelée immédiatement.
Quelqu'un peut-il expliquer ce que setTimeout
fait lorsque le délai est défini sur 0 millisecondes?
Quelques faits utiles pourraient aider à clarifier ce qui se passe:
setTimeout
ajoute un message (avec le rappel fourni) à la fin de cette file d'attente une fois le délai spécifié écoulé.(Remarque: cela signifie que le retard dans un appel setTimeout
n'est pas une chose sûre; c'est le délai minimum avant l'exécution du rappel . Le temps réel nécessaire dépend du temps qu'il faut pour traiter les messages qui le précèdent dans la file d'attente.)
Que se passe-t-il si le délai est défini sur 0
? Un nouveau message est immédiatement ajouté à la file d'attente et sera traité lorsque le code en cours d'exécution sera terminé et que tous les messages ajoutés précédemment auront été traités.
Lorsque vous appelez setTimeout
…
setTimeout(function() {
console.log('AAA');
}, 0);
… Un message est ajouté à la file d'attente avec le rappel spécifié. Le reste de votre code…
for (i = 0; i < 1000; i++) {
console.log('BBB');
}
// etc.
… Continue de s'exécuter de manière synchrone. Une fois complètement terminée, la boucle d'événements interroge la file d'attente de messages pour le message suivant et trouve celle avec votre rappel setTimeout
, qui est ensuite traitée (le rappel est exécuté).
Le rappel n'est exécuté que - après le code en cours d'exécution est terminé, peu importe le temps que cela prend.
Pour plus de détails sur la boucle d'événements, voir: