La programmation non synchrone, également connue sous le nom de programmation asynchrone, est un paradigme de programmation largement utilisé dans JavaScript pour gérer les opérations qui ne doivent pas bloquer l’exécution du code. Cela permet d’exécuter plusieurs tâches en parallèle sans attendre que chacune d’elles soit terminée avant de passer à la suivante. Cette approche est particulièrement utile pour les opérations d’entrée-sortie (E/S) telles que les requêtes réseau, les lectures/écritures de fichiers, etc., qui peuvent prendre un certain temps pour se terminer.
En JavaScript, la programmation asynchrone est mise en œuvre à l’aide de callbacks, de Promises et, plus récemment, des fonctions async/await introduites dans ECMAScript 2017.

Les callbacks sont une technique classique utilisée pour gérer les opérations asynchrones en JavaScript. Ils sont passés en tant qu’arguments à des fonctions, qui seront appelées une fois que l’opération asynchrone est terminée. Cependant, la gestion des callbacks peut rapidement devenir complexe, en particulier lorsqu’il s’agit de plusieurs opérations asynchrones imbriquées, ce qui conduit souvent à ce que l’on appelle « l’enfer des callbacks » ou « callback hell ».
Pour remédier à cela, les Promises ont été introduites dans ECMAScript 2015 (également connu sous le nom d’ES6). Les Promises sont des objets qui représentent l’achèvement ou l’échec éventuel d’une opération asynchrone, et elles offrent une syntaxe plus propre et plus facile à lire que les callbacks. Avec les Promises, vous pouvez enchaîner des opérations asynchrones de manière séquentielle, ce qui rend le code plus lisible et plus facile à maintenir.
La syntaxe des Promises ressemble à ceci :
javascriptconst maPromesse = new Promise((resolve, reject) => {
// Code asynchrone ici
if (/* opération réussie */) {
resolve('Résultat de l\'opération');
} else {
reject('Erreur rencontrée');
}
});
maPromesse.then((resultat) => {
console.log(resultat);
}).catch((erreur) => {
console.error(erreur);
});
La méthode then
est utilisée pour traiter le résultat de la Promesse lorsqu’elle est résolue avec succès, tandis que la méthode catch
est utilisée pour gérer les erreurs éventuelles.
Plus récemment, les fonctions async/await ont été introduites dans ECMAScript 2017 pour simplifier encore davantage la gestion des opérations asynchrones. Les fonctions async sont des fonctions qui retournent une Promise, ce qui permet d’utiliser le mot-clé await
à l’intérieur de ces fonctions pour attendre que d’autres Promises se résolvent ou soient rejetées. Cela permet d’écrire du code asynchrone de manière synchrone, ce qui le rend beaucoup plus lisible et plus intuitif pour les développeurs.
Voici un exemple d’utilisation des fonctions async/await :
javascriptasync function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Erreur lors de la récupération des données :', error);
}
}
fetchData();
Dans cet exemple, la fonction fetchData
est marquée comme étant async
, ce qui signifie qu’elle retourne une Promise. À l’intérieur de cette fonction, le mot-clé await
est utilisé pour attendre que la Promesse retournée par la fonction fetch
se résolve avec succès, puis pour attendre que la Promesse retournée par la méthode json()
se résolve également avec succès.
En résumé, la programmation non synchrone en JavaScript permet d’exécuter efficacement des opérations asynchrones sans bloquer l’exécution du code, ce qui améliore la réactivité des applications web et offre une meilleure expérience utilisateur.
Plus de connaissances
Bien sûr, plongeons plus en détail dans la programmation asynchrone en JavaScript.
- Callbacks :
Les callbacks sont la manière traditionnelle de gérer les opérations asynchrones en JavaScript. Un callback est simplement une fonction passée en tant qu’argument à une autre fonction, qui sera invoquée une fois que l’opération asynchrone est terminée. Voici un exemple simple :
javascriptfunction fetchData(callback) {
setTimeout(() => {
const data = 'Données récupérées';
callback(data);
}, 1000);
}
function afficherData(data) {
console.log(data);
}
fetchData(afficherData);
Dans cet exemple, la fonction fetchData
simule une opération asynchrone en utilisant setTimeout
pour attendre une seconde avant de retourner les données. Une fois les données récupérées, la fonction de rappel afficherData
est appelée pour les afficher.
Cependant, l’utilisation excessive de callbacks peut entraîner un code difficile à lire et à maintenir, en particulier avec des opérations asynchrones imbriquées, ce qui conduit souvent à ce que l’on appelle « l’enfer des callbacks ».
- Promises :
Les Promises ont été introduites pour remédier aux inconvénients des callbacks en offrant une syntaxe plus claire et une meilleure gestion des erreurs. Une Promise représente l’achèvement ou l’échec éventuel d’une opération asynchrone, et elle peut être dans l’un des trois états suivants : pending (en attente), fulfilled (réalisée) ou rejected (rejetée).
Voici un exemple utilisant des Promises :
javascriptfunction fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Données récupérées';
resolve(data);
}, 1000);
});
}
fetchData()
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
Dans cet exemple, la fonction fetchData
retourne une Promise qui se résout avec succès après une seconde. La méthode then
est utilisée pour traiter le résultat lorsque la Promise est résolue, et la méthode catch
est utilisée pour gérer les erreurs éventuelles.
Les Promises offrent également la possibilité d’enchaîner des opérations asynchrones de manière séquentielle, ce qui améliore la lisibilité du code et évite l’enfer des callbacks.
- Async/Await :
Les fonctions async/await sont une syntaxe introduite dans ECMAScript 2017 pour simplifier davantage la gestion des opérations asynchrones. Les fonctionsasync
retournent toujours une Promise, et le mot-cléawait
est utilisé à l’intérieur de ces fonctions pour attendre la résolution ou le rejet d’une Promise.
Voici l’exemple précédent utilisant async/await :
javascriptasync function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = 'Données récupérées';
resolve(data);
}, 1000);
});
}
async function afficherData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}
afficherData();
Dans cet exemple, la fonction afficherData
est déclarée comme étant async
, ce qui lui permet d’utiliser le mot-clé await
pour attendre que la Promesse retournée par fetchData
soit résolue. Cela rend le code plus lisible et plus proche de la syntaxe synchrone.
En conclusion, la programmation asynchrone en JavaScript est essentielle pour créer des applications web réactives et efficaces. Les callbacks, les Promises et les fonctions async/await sont des outils puissants pour gérer les opérations asynchrones, et le choix entre eux dépend souvent de la complexité du code et des préférences personnelles du développeur.