Maison  >  Article  >  interface Web  >  JavaScript asynchrone : promesses vs Async/Await dans les détails

JavaScript asynchrone : promesses vs Async/Await dans les détails

WBOY
WBOYoriginal
2024-09-03 15:21:29881parcourir

Asynchronous JavaScript: Promises vs. Async/Await in Details

La programmation asynchrone est essentielle au développement Web moderne, en particulier en JavaScript. Traditionnellement, les langages de programmation exécutent le code de manière séquentielle de haut en bas. Cependant, ce modèle d'exécution synchrone peut conduire à des inefficacités, en particulier lorsqu'il s'agit d'opérations chronophages telles que la récupération de données sur un serveur, l'accès à des fichiers ou l'exécution de calculs complexes. La programmation asynchrone répond à ces défis en permettant à certains processus de s'exécuter indépendamment du thread d'exécution principal, améliorant ainsi la réactivité et les performances des applications Web.

Intrinsèquement monothread, JavaScript utilise une programmation asynchrone pour gérer les opérations qui autrement bloqueraient le thread d'exécution jusqu'à son achèvement. Ceci est réalisé grâce à des fonctionnalités telles que les rappels, les promesses et la syntaxe async/wait, qui aident à gérer les opérations dont le temps d'exécution est intrinsèquement incertain. L’importance de maîtriser la programmation asynchrone en JavaScript ne peut être surestimée. Il permet aux développeurs de créer des expériences Web plus fluides, plus rapides et plus interactives. Alors que les sites Web et les applications Web deviennent de plus en plus complexes et axés sur les données, la gestion efficace des opérations asynchrones est cruciale pour maintenir les performances et offrir une expérience utilisateur transparente.

Essentiellement, la programmation asynchrone optimise non seulement les performances des applications Web en empêchant le blocage du thread principal, mais contribue également de manière significative à l'évolutivité et à la maintenabilité de la base de code. Au fur et à mesure que nous approfondirons ce sujet, nous explorerons les mécanismes et les modèles fournis par JavaScript pour gérer les opérations asynchrones et pourquoi ils sont indispensables dans la boîte à outils des développeurs Web modernes.

Comprendre le Javascript asynchrone

Imaginez passer votre commande au comptoir d'un café animé. Au lieu d'attendre que votre boisson soit préparée, vous vous asseyez et parcourez un magazine. Pendant ce temps, le barista travaille sur votre commande. Une fois votre café prêt, le barista vous appelle pour venir le chercher. Ce scénario est similaire au fonctionnement des opérations asynchrones en JavaScript.

En JavaScript, les opérations asynchrones reviennent à envoyer votre commande à la cuisine ; vous n’êtes pas obligé de rester debout et d’attendre que le cuisinier ait fini. Vous pouvez continuer à lire votre livre, discuter avec un ami ou profiter de la musique au café. Vous serez averti une fois que votre commande sera prête et vous pourrez déguster votre repas. De même, JavaScript asynchrone permet à des tâches telles que des appels d'API ou des opérations sur des fichiers de s'exécuter en arrière-plan. Comme vous au café, le programme principal n’est pas bloqué ; il continue de s'exécuter et de répondre aux entrées ou actions d'autres utilisateurs.

Opérations asynchrones courantes en JavaScript

Appels API : C'est comme commander de la nourriture auprès d'un service de livraison tout en regardant un film. Vous ne mettez pas le film en pause pour attendre la nourriture ; vous continuez à regarder, et quand la sonnette retentit, vous récupérez votre nourriture. Dans le développement Web, demander des données à un serveur fonctionne de la même manière. Vous demandez des données et continuez à interagir avec le site, et elles vous sont affichées une fois les données arrivées.

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json()) // Convert the response to JSON
  .then(data => console.log(data))    // Log the data
  .catch(error => console.error('Error:', error)); // Handle any errors

Opérations sur les fichiers : Cela revient à envoyer des documents à imprimer sur une imprimante pendant que vous rangez votre bureau. Vous n’avez pas besoin de rester près de l’imprimante à attendre tous vos documents ; vous continuez à accomplir vos autres tâches. De même, les opérations sur les fichiers en JavaScript (en particulier sur les plateformes comme Node.js) vous permettent de lancer une opération de lecture ou d'écriture de fichier, puis de passer à d'autres tâches, en recevant une notification lorsque l'opération est terminée.

const fs = require('fs');

fs.readFile('example.txt', 'utf8', (err, data) => {
  if (err) {
    console.error('Error reading the file:', err);
    return;
  }
  console.log(data); // Log the contents of the file
});

Minuteries et délais : Utiliser setTimeout() ou setInterval() en JavaScript, c'est comme régler une minuterie de four lors de la cuisson d'un gâteau. Vous réglez la minuterie et laissez le four faire son travail pendant que vous préparez du glaçage. La minuterie n'arrête pas vos autres activités ; il vous avertit simplement quand passer à l'étape suivante.

setTimeout(() => {
  console.log('This message appears after 2 seconds!');
}, 2000);

Auditeurs d'événements : Imaginez installer un capteur de mouvement dans votre jardin qui sonne lorsqu'il détecte un mouvement. C'est ainsi que fonctionnent les écouteurs d'événements. Vous les configurez pour surveiller certains événements (comme les clics ou les frappes au clavier) et ils exécutent les fonctions associées en réponse sans interférer avec les autres opérations de votre application.

document.getElementById('myButton').addEventListener('click', () => {
  console.log('Button was clicked!');
});

Promises

Imagine you're at a carnival and just tossed a ring towards a bottle, aiming to hook it. At that moment, three outcomes are possible: the ring lands perfectly (success), misses entirely (failure), or is still spinning in the air (pending). In JavaScript, this scenario is analogous to a Promise. A Promise is an object that represents the eventual completion or failure of an asynchronous operation. It’s like making a bet on whether the ring will land.

Anatomy of a Promise

Pending: The Promise is initially in the "pending" state. It's uncertain, like the ring spinning in the air.

Fulfilled: If the asynchronous operation completes successfully, the Promise is "fulfilled." Think of this as the ring landing on the bottle.

Rejected: If the operation fails or encounters an error, the Promise is "rejected." This is akin to the ring missing the target.

Creating a Promise Instance

Here is how you can create a promise for the above example:

const ringToss = new Promise((resolve, reject) => {
  let hasLanded = Math.random() > 0.5; // Random chance of success
  if (hasLanded) {
    resolve('You won a prize!'); // Fulfill the promise
  } else {
    reject('Try again!'); // Reject the promise
  }
});

console.log(ringToss); // Logs the Promise object showing its state

Working with Promises

Now that you've tossed the ring, you need strategies to handle the outcome, whether a win or a miss.

Methods to Handle Promises

.then(): This method is used when the promise is fulfilled. It’s like claiming your prize at the carnival booth.

.catch(): This handles rejections or errors. It’s the equivalent of deciding what to do after you miss the ring toss.

.finally(): This method is for code that runs regardless of the outcome, similar to walking away from the booth after winning or losing.

Chaining Promises

Chaining promises is like playing several carnival games in a row. You must complete one game to receive a token that lets you play the next.

enterBooth()
  .then(token => playGameOne(token))
  .then(prize => tradeForToken(prize))
  .then(token => playGameTwo(token))
  .then(prize => console.log(`You won: ${prize}`))
  .catch(error => console.error('Game error:', error));

In the example of chaining promises above, each step represents a sequential operation, each dependent on the success of the previous one. Here’s what happens in each step:

enterBooth(): This is likely the initial step where you "enter" the asynchronous operation. Imagine it as signing up or logging into an online service. This function returns a Promise.

.then(token => playGameOne(token)): Once you successfully enter, you receive a token. This token is then used to play the first game. This step is also a Promise, dependent on obtaining the token from enterBooth().

.then(prize => tradeForToken(prize)): If you win the first game, you receive a prize. This prize must be traded for another token to continue to the next game. This trading action is another asynchronous operation that returns a Promise.

.then(token => playGameTwo(token)): With the new token, you can play the second game. Again, this step is only possible if the previous step of trading the prize for a token is successful.

.then(prize => console.log(You won: ${prize})): If the second game is won, you will receive another prize. This prize is logged to the console, indicating the successful end of this promise chain.

You might be wondering when the .catch block comes into play. The .catch() block is invoked if any of the Promises in the chain fail or are rejected. This could happen if:

*You failed to enter the booth (enterBooth() fails).
*Any game along the way (playGameOne() or playGameTwo()) does not result in a prize.
*The prize cannot be traded for a token.

In any of these scenarios, the .catch() block catches the error, logs it or takes other corrective action. This prevents the error from stopping the entire script and allows for graceful error handling.

Final Words

Choosing between Promises and Async/Await largely depends on your project's specific needs. Async/Await might be the clearer choice for complex sequences of dependent operations due to its straightforward syntax and ease of error handling. Conversely, when dealing with multiple, simultaneous operations that do not depend on each other, utilizing Promises with techniques like Promise.all can significantly enhance performance. Both tools are essential in a JavaScript developer’s toolkit, empowering you to write more efficient, cleaner code.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn