W3docs

Les callbacks en JavaScript

En JavaScript, les callbacks sont un concept essentiel qui permet aux développeurs de gérer efficacement les opérations asynchrones.

Un callback est simplement une fonction que vous passez en argument à une autre fonction, afin que la fonction réceptrice puisse l'appeler ultérieurement. Puisque les fonctions sont des valeurs de première classe en JavaScript — elles peuvent être stockées dans des variables, transmises et retournées — n'importe quelle fonction peut accepter une autre fonction en paramètre. Cette seule idée est à l'origine de tout, des méthodes de tableau comme map aux minuteries et aux requêtes réseau.

Ce chapitre explique ce que sont les callbacks, la différence entre les callbacks synchrones et asynchrones, la convention error-first, le problème du callback hell qu'ils engendrent, et comment les Promises et async/await le résolvent.

Un premier callback

La fonction que vous passez est le callback ; la fonction qui la reçoit et l'invoque est la fonction d'ordre supérieur. Ici, un callback s'exécute une fois qu'un travail est terminé :

javascript— editable

finishTask est passé à completeTask et invoqué à l'intérieur. Notez que vous passez le nom de la fonction (finishTask) sans parenthèses — les ajouter l'appellerait immédiatement et transmettrait sa valeur de retour à la place.

Callbacks synchrones et asynchrones

Tous les callbacks ne concernent pas l'attente. Il existe deux types distincts, et les confondre est une source fréquente de bugs.

Callbacks synchrones

Un callback synchrone s'exécute immédiatement, dans l'ordre, avant que la fonction externe ne retourne. Les méthodes de tableau en sont l'exemple classique :

javascript— editable

Ici, transform est appelé et terminé pour chaque élément avant que map ne retourne. Les méthodes intégrées telles que Array.prototype.map, filter, forEach et sort prennent toutes des callbacks synchrones.

Callbacks asynchrones

Un callback asynchrone est confié à une opération qui se termine plus tard — une minuterie, une lecture de fichier ou une requête réseau. La fonction externe retourne immédiatement, et le callback se déclenche une fois le résultat disponible. JavaScript planifie ces opérations via la boucle d'événements, qui met les callbacks en file d'attente et les exécute lorsque la pile d'appels est vide.

javascript— editable

Même avec un délai de 0 ms, le callback s'exécute après le code synchrone environnant. C'est la caractéristique définissante d'un callback async : il ne peut pas retourner une valeur de manière habituelle, donc la seule façon d'utiliser le résultat est de placer votre code de continuation à l'intérieur du callback. Pour comprendre exactement quand ceux-ci s'exécutent, consultez JavaScript : Event Loop.

La convention error-first

Les callbacks async ne peuvent pas throw vers le code qui a lancé l'opération — au moment où ils s'exécutent, ce code est déjà retourné depuis longtemps. La communauté a adopté une convention : passer l'erreur comme premier argument, et le résultat comme second. Le callback vérifie toujours l'erreur en premier.

javascript— editable

Lorsque tout réussit, le slot d'erreur est null. Cette signature (err, result) est la norme dans les API Node.js (fs.readFile, dns.lookup et bien d'autres).

Callback hell : la pyramide de la doom

Les callbacks fonctionnent bien pour une seule opération. Les problèmes commencent lorsqu'une étape async dépend du résultat de la précédente. Chaque étape s'imbrique dans la précédente, et l'indentation progresse vers la droite — c'est la fameuse pyramide de la doom :

javascript— editable

Avec deux étapes, c'est encore lisible. Ajoutez-en une troisième et une quatrième — et répétez la vérification if (err) à chaque niveau — et le code devient difficile à suivre, à gérer en termes d'erreurs, et à modifier. C'est le callback hell, et c'est la principale raison pour laquelle les Promises ont été introduites.

Bonnes pratiques pour l'utilisation des callbacks

Bien que les callbacks soient puissants, leur utilisation excessive ou incorrecte peut mener au « callback hell », où le code s'imbrique trop profondément et devient difficile à lire et à maintenir. Voici quelques bonnes pratiques pour garder votre code propre :

  1. Modularisez votre code : Décomposez vos fonctions callback en fonctions plus petites et réutilisables. Cette approche améliore non seulement la lisibilité, mais aussi la maintenance du code.
  2. Gérez les erreurs avec élégance : Gérez toujours les erreurs dans vos callbacks. Cette pratique évite les plantages et les comportements indésirables en production.
  3. Évitez l'imbrication profonde : Essayez d'aplatir vos structures de callbacks autant que possible. Des outils comme async/await ou les Promises peuvent aider à gérer les opérations asynchrones de manière plus propre.
  4. Faites attention aux fermetures dans les boucles : Lors de la définition de callbacks à l'intérieur de boucles, utilisez let ou const pour les variables de boucle afin d'éviter les bugs liés aux fermetures où tous les callbacks capturent la valeur finale de la boucle.

Aller au-delà des callbacks : Promises et Async/Await

Bien que les callbacks soient une partie fondamentale de JavaScript, le JavaScript moderne offre des façons plus abstraites de gérer le code asynchrone, telles que les Promises et async/await.

Utiliser les Promises

Une Promise représente une valeur qui peut être disponible maintenant, dans le futur, ou jamais. Au lieu de l'imbrication, les étapes dépendantes sont enchaînées les unes après les autres, ce qui aplatit la pyramide et centralise la gestion des erreurs dans un seul .catch. Commencez avec JavaScript : Promises, puis voyez comment les étapes se connectent dans JavaScript : Chaînage de Promises.

Si vous disposez d'une ancienne fonction basée sur des callbacks (comme les exemples divide ou getUser ci-dessus), vous pouvez l'envelopper pour qu'elle retourne une Promise — une technique appelée promisification. Voir JavaScript : Promisification.

Async/Await : une approche plus claire

La syntaxe async/await vous permet d'écrire du code asynchrone qui se lit comme du code synchrone. Elle est construite au-dessus des Promises et est plus intuitive que les patterns traditionnels de callbacks. Lisez JavaScript : Async/Await pour voir comment vous pouvez utiliser async/await à la place des callbacks.

Conclusion

Comprendre et utiliser efficacement les callbacks est crucial pour les développeurs JavaScript. En suivant les bonnes pratiques et en utilisant des fonctionnalités modernes comme les Promises et async/await, vous pouvez écrire du code plus propre et plus maintenable. Maîtrisez ces concepts pour améliorer vos compétences en programmation JavaScript et créer des applications plus efficaces.

Pratique

Pratique
Qu'est-ce qu'une fonction callback en JavaScript et quand est-elle exécutée ?
Qu'est-ce qu'une fonction callback en JavaScript et quand est-elle exécutée ?
Was this page helpful?