Callback en JavaScript : passer une fonction à exécuter plus tard

Un callback est une fonction confiée à une autre pour être appelée en temps voulu : la convention erreur en premier, la pyramide et la sortie par les promesses.
3 min de lecture
Believemy logo

Avant les promesses, il fallait bien un moyen de dire au langage : voici ce qu'il faudra faire quand ce sera prêt. La réponse tient en une idée simple, et aussi vieille que JavaScript.

On passe la suite du travail sous forme de fonction, et c'est le code appelé qui décide du moment où il la déclenche.


Définition

Un callback, ou fonction de rappel, est une function passée en argument à une autre fonction, laquelle se charge de l'appeler. Elle n'est pas exécutée à l'endroit où on l'écrit, elle est confiée.

JAVASCRIPT
const utilisateurs = ["Chloé", "Marc", "Inès"];

// Appelé tout de suite, une fois par élément
utilisateurs.forEach((nom) => console.log(nom));

// Mis de côté, et appelé une seconde plus tard
setTimeout(() => console.log("Une seconde s'est écoulée"), 1000);

Les deux écritures portent le même nom et ne font pas du tout la même chose. Array.forEach() rappelle immédiatement, setTimeout() rappelle plus tard. La différence ne se voit pas dans la syntaxe, seulement dans la documentation de la fonction appelée.


La convention erreur en premier

Une opération qui peut échouer doit pouvoir annoncer son échec. Node.js a imposé une règle devenue un standard : le callback reçoit l'erreur en premier argument, le résultat en second.

JAVASCRIPT
function lireConfig(chemin, callback) {
  if (!chemin) return callback(new Error("Chemin manquant"));
  callback(null, { theme: "sombre" });
}

lireConfig("app.json", (err, config) => {
  if (err) return console.log("Échec :", err.message);
  console.log(config.theme);   // sombre
});

Le null en première position signifie que rien n'a cassé. Un callback qui ne teste pas err avale les échecs en silence, et c'est de loin le défaut le plus fréquent de ce style d'écriture.


La pyramide, et pourquoi on en est sorti

Un callback dans un callback dans un callback : chaque étape décale la suivante vers la droite, et le test d'erreur se répète à chaque niveau.

JAVASCRIPT
lireConfig("app.json", (err, config) => {
  if (err) return console.log(err.message);
  lireProfil(config, (err, profil) => {
    if (err) return console.log(err.message);
    lireFactures(profil, (err, factures) => {
      if (err) return console.log(err.message);
      console.log(factures.length);
    });
  });
});

Une Promise règle les deux problèmes ensemble : la suite d'étapes redevient plate avec then(), et un seul catch couvre toute la chaîne. Avec async et await, il ne reste que trois lignes qui se lisent de haut en bas.

Bon à savoir

Le callback n'a pas disparu pour autant. Les méthodes de tableau comme Array.map() ou Array.filter() en prennent un, addEventListener aussi, et tout ce qui se déclenche plusieurs fois continue d'en dépendre. Seules les opérations à résultat unique sont passées aux promesses.


Questions fréquentes

Question

Un callback est-il forcément asynchrone ?

Non, et la confusion est tenace. Le callback de forEach ou de map s'exécute immédiatement, sur place, avant la ligne suivante. Celui de setTimeout attend son tour. Le mot ne dit rien du moment de l'appel : il faut regarder ce que fait la fonction qui le reçoit.


Question

Pourquoi mon callback perd-il la valeur de this ?

Parce qu'une fonction classique reçoit son this de la façon dont elle est appelée, et le code qui la rappelle l'appelle sans contexte. Une fonction fléchée règle le problème : elle n'a pas de this propre et garde celui de l'endroit où elle a été écrite.


Question

Faut-il encore apprendre ce style ?

Oui, car il est partout : événements du navigateur, méthodes de tableau, bibliothèques anciennes que l'on croise encore. Comprendre le callback rend d'ailleurs les promesses beaucoup plus claires, puisqu'elles ne font qu'organiser la même idée. Les deux styles sont travaillés côte à côte dans la formation JavaScript.

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.