Quelles sont les fonctions de la temporisation intégrées en Node.js

Comment temporiser les actions avec des fonctions “timer” côté serveur pour jouer avec la boucle d'évènement ? Une traduction de l'article What are the built-in timer functions?

Classée dans Conventions JavaScript

Traduction

Les deux plus courantes fonctions de temporisation intégrées (timer functions) sont setTimeout et setInterval. Elles peuvent être utilisées pour appeler une fonction à un moment ultérieur. Voici un exemple d'utilisation :

setTimeout(function() { console.log("setTimeout : Ça fait une seconde !"); }, 1000);
setInterval(function() { console.log("setInterval : Ça fait une seconde !"); }, 1000);

Avec comme exemple de sortie est :

setTimeout: It's been one second!
setInterval: It's been one second!
setInterval: It's been one second!
setInterval: It's been one second!
setInterval: It's been one second!
...

Comme vous pouvez le constater, les paramètres sont identiques dans les deux cas. Le deuxième paramètre indique combien de temps en millisecondes il faut attendre avant d'appeler la fonction transmise dans le premier paramètre. La différence entre les deux fonctions est que setTimeout n'appelle la fonction de rappel (callback function) qu'une seule fois, tandis que setInterval l'appelle encore et encore.

En règle générale, il convient d'être prudent avec setInterval, car il peut provoquer certains effets indésirables. Si, par exemple, vous vouliez vous assurer que votre serveur est opérationnel en lui envoyant une requête ping toutes les secondes, vous pourriez essayer quelque chose comme ceci :

setInterval(ping, 1000);

Cela peut toutefois poser des problèmes si votre serveur est lent et qu'il met, par exemple, 3 secondes à répondre à la première demande. Pendant le temps nécessaire à l'obtention de la réponse, vous auriez envoyé 3 autres demandes - ce qui n'est pas vraiment souhaitable ! Dans l'ensemble, cela n'a pas un grand impact lorsque vous servez de petits fichiers statiques. Mais si vous effectuez une opération coûteuse, comme une requête de base de données ou tout autre calcul complexe, cela peut avoir des résultats indésirables. Une solution courante ressemble à ceci :

const recursive = function () {
    console.log("Cela fait une seconde !");
    setTimeout(recursive, 1000);
}
recursive();

Comme vous pouvez le voir, elle fait un appel à la fonction recursive qui, lorsqu'elle se termine, fait un appel à setTimeout(recursive, 1000) qui la fait appeler à nouveau récursive dans 1 seconde - ce qui a pratiquement le même effet que setInterval tout en étant résistant aux erreurs involontaires qui peuvent s'accumuler.

Vous pouvez effacer les temporisations que vous avez définies avec clearTimeout et clearInterval. Leur utilisation est très simple :

function never_call () {
  console.log("Vous ne devriez jamais appeler cette fonction");
}

const id1 = setTimeout(never_call,1000);
const id2 = setInterval(never_call,1000);

clearTimeout(id1);
clearInterval(id2);

Ainsi, si vous gardez une trace des valeurs de retour des temporisateurs, vous pouvez facilement supprimer les temporisateurs.

L'astuce finale pour les objets temporisés est que vous pouvez passer des paramètres à la fonction de rappel en passant plus de paramètres à setTimeout et setInterval :

setTimeout(console.log, 1000, "Ceci", "a", 4, "paramètres");
setInterval(console.log, 1000, "Cela n'en a qu'un");

Avec comme sortie :

Ceci a 4 paramètres
Cela n'en a qu'un
Cela n'en a qu'un
Cela n'en a qu'un
Cela n'en a qu'un
Cela n'en a qu'un
...

setImmediate()

setImmediate() est une autre fonction de temporisation intégrée qui, comme son nom l'indique, s'exécute immédiatement après la fin de la première itération de la boucle d'événement. En d'autres termes, setImmediate() est similaire à une fonction setTimeout() avec un délai de 0ms. La fonction setImmediate() peut également prendre des paramètres supplémentaires qui sont transmis lorsque la fonction de rappel est appelée :

console.log("Ceci sera imprimé en premier");
setImmediate(console.log, "Ceci est un paramètre supplémentaire");
console.log("Ceci sera imprimé en second");

Avec comme sortie :

Ceci sera imprimé en premier
Ceci sera imprimé en second
Ceci est un paramètre supplémentaire

Rappelez-vous que même si setImmediate() n'a pas de délai (c.-à-d. 0ms), cela ne signifie pas que le code s'exécutera de manière synchrone. Cela signifie simplement qu'il n'y aura pas de délai (c.-à-d. 0 ms) après la fin de la première itération de la boucle d'événements, c'est-à-dire après l'exécution de toutes les commandes synchrones.

Lire dans une autre langue