Je suppose qu'une fois qu'il est exécuté, il est dans la file d'attente, mais dans la file d'attente, y a-t-il une assurance qu'il se déclenchera exactement après X millisecondes? Ou d'autres tâches lourdes plus élevées dans la file d'attente le retarderont-elles?
javascript
node.js
serverside-javascript
MyCodeGone
la source
la source
Réponses:
La sémantique de setTimeout est à peu près la même que dans un navigateur web: le timeout arg est un nombre minimum de ms à attendre avant de s'exécuter, pas une garantie. De plus, passer 0, un non-nombre ou un nombre négatif le fera attendre un nombre minimum de ms. Dans Node, cela fait 1 ms, mais dans les navigateurs, cela peut aller jusqu'à 50 ms.
La raison en est qu'il n'y a pas de préemption de JavaScript par JavaScript. Prenons cet exemple:
Le flux ici est:
Si ce n'était pas le cas, alors vous pourriez avoir un bit de JavaScript "interrompre" un autre. Nous aurions à mettre en place des mutex et des sémaphores et autres, pour éviter qu'un code comme celui-ci soit extrêmement difficile à raisonner:
Le caractère unique de l'exécution JavaScript de Node le rend beaucoup plus simple à utiliser que la plupart des autres styles de concurrence. Bien sûr, le compromis est qu'il est possible pour une partie mal comportée du programme de bloquer le tout avec une boucle infinie.
Est-ce un meilleur démon à combattre que la complexité de la préemption? Ça dépend.
la source
console.log
message exceptionnellement précis .L'idée du non-blocage est que les itérations de boucle sont rapides. Ainsi, l'itération pour chaque tick devrait prendre suffisamment de temps pour que setTimeout soit précis avec une précision raisonnable (peut-être <100 ms environ).
En théorie, vous avez raison. Si j'écris une application et bloque la coche, setTimeouts sera retardé. Donc, pour répondre à votre question, qui peut assurer l'exécution de setTimeouts à temps? En écrivant un code non bloquant, vous pouvez contrôler le degré de précision jusqu'à presque n'importe quel degré de précision raisonnable.
Tant que javascript est "mono-thread" en termes d'exécution de code (à l'exclusion des web-workers et autres), cela se produira toujours. La nature à un seul thread est une énorme simplification dans la plupart des cas, mais nécessite l'idiome non bloquant pour réussir.
Essayez ce code soit dans votre navigateur, soit dans node, et vous verrez qu'il n'y a aucune garantie de précision, au contraire, le setTimeout sera très tardif:
À moins que l'interpréteur n'optimise la boucle (ce qu'il ne fait pas sur chrome), vous obtiendrez quelque chose dans les milliers. Retirez la boucle et vous verrez que c'est 500 sur le nez ...
la source
La seule façon de s'assurer que le code est exécuté est de placer votre logique setTimeout dans un processus différent.
Utilisez le module de processus enfant pour générer un nouveau programme node.js qui fait votre logique et transmet les données à ce processus via une sorte de flux (peut-être tcp).
De cette façon, même si un long code de blocage est en cours d'exécution dans votre processus principal, votre processus enfant a déjà démarré et placé un setTimeout dans un nouveau processus et un nouveau thread et s'exécutera donc lorsque vous vous y attendez.
Une complication supplémentaire se situe au niveau du matériel où vous avez plus de threads en cours d'exécution que de processus et donc le changement de contexte entraînera des retards (très mineurs) par rapport à votre timing attendu. Cela devrait être négligeable et si cela est important, vous devez sérieusement réfléchir à ce que vous essayez de faire, pourquoi vous avez besoin d'une telle précision et quel type de matériel alternatif en temps réel est disponible pour faire le travail à la place.
En général, l'utilisation de processus enfants et l'exécution de plusieurs applications de nœuds en tant que processus séparés avec un équilibreur de charge ou un stockage de données partagé (comme redis) est important pour faire évoluer votre code.
la source
setTimeout
est une sorte de Thread , il tient une opération pendant un temps donné et s'exécute.ici, le premier argument doit être un type de fonction; à titre d'exemple, si vous souhaitez imprimer votre nom après 3 secondes, votre code devrait être quelque chose comme ci-dessous.
Le point clé à retenir est que ce que vous voulez faire en utilisant la
setTimeout
méthode, faites-le dans une fonction . Si vous souhaitez appeler une autre méthode en analysant certains paramètres, votre code devrait ressembler à ci-dessous:la source
setTimeout(callback,t)
est utilisé pour exécuter un rappel après au moins t milliseconde . Le délai réel dépend de nombreux facteurs externes tels que la granularité du minuteur du système d'exploitation et la charge du système.Il est donc possible qu'il soit appelé légèrement après l'heure définie, mais qu'il ne soit jamais appelé avant.
la source