setTimeout() en JavaScript : exécuter du code après un délai

setTimeout() planifie un callback après un délai minimum : identifiant et clearTimeout, arguments supplémentaires, et la version qui rend une promesse.
3 min de lecture
Believemy logo

Fermer une notification au bout de trois secondes, relancer une requête après un échec, laisser une animation se terminer avant de changer d'écran : autant de moments où il faut simplement attendre.

Le langage n'a pas d'instruction pour cela, et c'est heureux : figer le fil unique gèlerait toute la page. L'environnement fournit un minuteur à la place.


Définition

setTimeout(callback, delai) confie une fonction à l'environnement, qui la déposera dans la file des tâches une fois le délai écoulé, exprimé en millisecondes. La ligne suivante s'exécute immédiatement, sans attendre.

JAVASCRIPT
console.log("avant");

const id = setTimeout(() => console.log("après 500 ms"), 500);

console.log("après, tout de suite");

// avant
// après, tout de suite
// après 500 ms

L'appel renvoie un identifiant, à conserver pour pouvoir annuler : clearTimeout(id) retire le callback de la file s'il n'est pas encore parti. Annuler un minuteur déjà déclenché ne provoque aucune erreur.


Le délai est un plancher, pas une garantie

Le nombre passé indique le moment à partir duquel le callback devient éligible. Il s'exécutera à ce moment-là seulement si la pile d'appels est libre, ce qui explique tous les retards observés.

  • Un traitement en cours retarde tout. Une fonction longue occupe le fil, et le callback attend son tour derrière elle.
  • Les délais s'imbriquent mal. Dans un navigateur, à partir de cinq minuteurs imbriqués, le délai minimal est ramené à quatre millisecondes par la spécification.
  • Un onglet en arrière-plan est ralenti. Les navigateurs espacent fortement les minuteurs d'un onglet caché pour économiser la batterie.
JAVASCRIPT
const t0 = Date.now();
setTimeout(() => console.log("prévu à 50 ms, réel :", Date.now() - t0), 50);

const fin = Date.now() + 200;
while (Date.now() < fin) {}   // le fil est occupé 200 ms


Une version qui rend une promesse

Un setTimeout emballé dans une Promise devient une pause utilisable avec await, et le code retrouve sa lecture verticale.

JAVASCRIPT
const pause = (ms) => new Promise((r) => setTimeout(r, ms));

async function reessayer(travail, essais = 3) {
  for (let i = 0; i < essais; i++) {
    try {
      return await travail();
    } catch (err) {
      if (i === essais - 1) throw err;
      await pause(200 * (i + 1));   // attente croissante entre deux essais
    }
  }
}
Bon à savoir

Les arguments placés après le délai sont transmis au callback : setTimeout(afficher, 100, "Chloé", 3) appellera afficher("Chloé", 3). Cela évite une fonction fléchée intermédiaire quand les valeurs sont déjà connues.


Questions fréquentes

Question

Que vaut vraiment setTimeout(fn, 0) ?

Il ne signifie pas tout de suite, mais dès que la pile sera libre. C'est la façon habituelle de repousser un traitement après la fin du code en cours, par exemple pour laisser le navigateur peindre une mise à jour avant de démarrer un calcul.


Question

Que contient l'identifiant renvoyé ?

Cela dépend de l'environnement : un simple nombre dans un navigateur, un objet Timeout sous Node.js. Traitez-le comme une valeur opaque, à passer telle quelle à clearTimeout, et ne comptez jamais sur son type dans un code partagé entre les deux.


Question

Pourquoi mon minuteur utilise-t-il une ancienne valeur ?

Parce que le callback lit la variable au moment où il s'exécute, pas au moment où il est planifié. Dans une boucle, un var partagé donnera la dernière valeur à tous les minuteurs, là où un let crée une liaison par tour et donne le résultat attendu.

Termes connexes

Découvrez notre glossaire JavaScript

Tous les mots de JavaScript expliqués simplement : mots-clés, objets natifs, méthodes, erreurs et concepts. Définitions claires et exemples qui tournent, pour apprendre et pour se dépanner.

Partager cet article

Tu veux nous aider ? Fais un lien vers cet article sur tes réseaux ou encore mieux : sur ton site, dans un article ou dans ta newsletter.