Quelle est la différence entre ces deux et quand vais-je utiliser l'un plutôt que l'autre?
javascript
node.js
Shlomi Schwartz
la source
la source
Réponses:
setTimeout revient simplement à appeler la fonction après la fin du délai. Chaque fois qu'une fonction est appelée, elle n'est pas exécutée immédiatement, mais mise en file d'attente afin qu'elle soit exécutée après que tous les gestionnaires d'événements en cours d'exécution et actuellement en file d'attente se terminent en premier. setTimeout (, 0) signifie essentiellement s'exécuter après l'exécution de toutes les fonctions actuelles de la file d'attente actuelle. Aucune garantie ne peut être donnée sur le temps que cela pourrait prendre.
setImmediate est similaire à cet égard, sauf qu'il n'utilise pas de file d'attente de fonctions. Il vérifie la file d'attente des gestionnaires d'événements d'E / S. Si tous les événements d'E / S de l'instantané actuel sont traités, il exécute le rappel. Il les met en file d'attente immédiatement après le dernier gestionnaire d'E / S, un peu comme process.nextTick. C'est donc plus rapide.
De plus, (setTimeout, 0) sera lent car il vérifiera la minuterie au moins une fois avant de s'exécuter. Parfois, cela peut être deux fois plus lent. Voici une référence.
var Suite = require('benchmark').Suite var fs = require('fs') var suite = new Suite suite.add('deffered.resolve()', function(deferred) { deferred.resolve() }, {defer: true}) suite.add('setImmediate()', function(deferred) { setImmediate(function() { deferred.resolve() }) }, {defer: true}) suite.add('setTimeout(,0)', function(deferred) { setTimeout(function() { deferred.resolve() },0) }, {defer: true}) suite .on('cycle', function(event) { console.log(String(event.target)); }) .on('complete', function() { console.log('Fastest is ' + this.filter('fastest').pluck('name')); }) .run({async: true})
Production
deffered.resolve() x 993 ops/sec ±0.67% (22 runs sampled) setImmediate() x 914 ops/sec ±2.48% (57 runs sampled) setTimeout(,0) x 445 ops/sec ±2.79% (82 runs sampled)
Le premier donne une idée des appels les plus rapides possibles. Vous pouvez vérifier vous-même si setTimeout est appelé deux fois moins que l'autre. Rappelez-vous également que setImmediate s'adaptera à vos appels au système de fichiers. Donc, sous charge, il sera moins performant. Je ne pense pas que setTimeout puisse faire mieux.
setTimeout est un moyen non intrusif d'appeler des fonctions après un certain temps. C'est comme si c'était dans le navigateur. Cela peut ne pas convenir pour le côté serveur (pensez pourquoi j'ai utilisé benchmark.js et non setTimeout).
la source
Un excellent article sur le fonctionnement de la boucle d'événements et efface certaines idées fausses. http://voidcanvas.com/setimmediate-vs-nexttick-vs-settimeout/
Citant l'article:
setImmediate
les rappels sont appelés une fois que les rappels de file d'attente d'E / S sont terminés ou expirés. Les rappels setImmediate sont placés dans la file d'attente de contrôle, qui sont traités après la file d'attente d'E / S.setTimeout(fn, 0)
les rappels sont placés dans la file d'attente du minuteur et seront appelés après les rappels d'E / S ainsi que les rappels de vérification de la file d'attente. En tant que boucle d'événements, traitez la file d'attente du minuteur en premier à chaque itération, de sorte que celle qui sera exécutée en premier dépend de la boucle d'événements de phase.la source
setImmediate () est de planifier l'exécution immédiate du rappel après les rappels d'événements d'E / S et avant setTimeout et setInterval.
setTimeout () est de planifier l'exécution d'un rappel unique après un délai de quelques millisecondes.
C'est ce que disent les documents.
setTimeout(function() { console.log('setTimeout') }, 0) setImmediate(function() { console.log('setImmediate') })
Si vous exécutez le code ci-dessus, le résultat sera comme ceci ... même si la documentation actuelle indique que "Pour planifier l'exécution" immédiate "du rappel après les rappels d'événements d'E / S et avant setTimeout et setInterval." ..
Résultat..
Si vous encapsulez votre exemple dans un autre minuteur, il imprime toujours setImmediate suivi de setTimeout.
setTimeout(function() { setTimeout(function() { console.log('setTimeout') }, 0); setImmediate(function() { console.log('setImmediate') }); }, 10);
la source
utilisez toujours
setImmediate
, sauf si vous êtes vraiment sûr que vous en avez besoinsetTimeout(,0)
(mais je ne peux même pas imaginer, pourquoi).setImmediate
callback sera presque toujours exécuté avantsetTimeout(,0)
, sauf lorsqu'il est appelé au premier tick et ausetImmediate
callback.la source
setTimeout
devrait être la référence, àsetImmediate
utiliser uniquement lorsque cela s'avère nécessaire.Totalement insatisfait des réponses fournies. J'ai posté ce que je pense être une meilleure réponse ici: https://stackoverflow.com/a/56724489/5992714
Questions est un doublon possible de Pourquoi le comportement de setTimeout (0) et setImmediate () est-il indéfini lorsqu'il est utilisé dans le module principal?
la source
Je pense que la réponse de Navya S n'est pas correcte, voici mon code de test:
let set = new Set(); function orderTest() { let seq = []; let add = () => set.add(seq.join()); setTimeout(function () { setTimeout(function () { seq.push('setTimeout'); if (seq.length === 2) add(); }, 0); setImmediate(function () { seq.push('setImmediate'); if (seq.length === 2) add(); }); }, 10); } // loop 100 times for (let i = 0; i < 100; i++) { orderTest(); } setTimeout(() => { // will print one or two items, it's random for (item of set) { console.log(item); } }, 100);
Les explications sont ici
la source
setTimeout (fn, 0) peut être utilisé pour empêcher le navigateur de se figer lors d'une mise à jour massive. par exemple dans websocket.onmessage, vous pouvez avoir des changements html, et si les messages continuent à arriver, le navigateur peut se figer lors de l'utilisation de setImmidiate
la source
Pour les comprendre profondément, veuillez une fois passer par les phases de la boucle d'événements.
SetImmediate: Il est exécuté dans la phase de "vérification". La phase de contrôle est appelée après la phase d'E / S.
SetTimeOut: Il est exécuté dans la phase "timer". La phase de temporisation est la première phase mais est appelée après la phase d' E / S ainsi que la phase de vérification .
Pour obtenir la sortie d'une manière déterministe, cela dépendra de la phase de la boucle d'événements; en conséquence, nous pouvons utiliser la fonction sur deux.
la source
utilisez setImmediate () pour ne pas bloquer la boucle d'événements. Le rappel s'exécutera sur la prochaine boucle d'événements, dès que celle en cours sera terminée.
utilisez setTimeout () pour contrôler les délais. La fonction s'exécutera après le délai spécifié. Le délai minimum est de 1 milliseconde.
la source