Maison > interface Web > js tutoriel > le corps du texte

Maîtriser les modèles asynchrones JavaScript : des rappels à l'asynchrone/à l'attente

Patricia Arquette
Libérer: 2024-09-13 20:16:39
original
390 Les gens l'ont consulté

Mastering JavaScript Async Patterns: From Callbacks to Async/Await

Lorsque j'ai découvert JavaScript asynchrone pour la première fois, j'ai eu du mal avec les rappels et je n'avais aucune idée du fonctionnement des promesses sous le capot. Au fil du temps, l'apprentissage des promesses et de l'async/wait a transformé mon approche du codage, le rendant beaucoup plus gérable. Dans ce blog, nous explorerons ces modèles asynchrones étape par étape, révélant comment ils peuvent rationaliser votre processus de développement et rendre votre code plus propre et plus efficace. Plongeons-nous et découvrons ces concepts ensemble !

Pourquoi avez-vous besoin d’apprendre le JavaScript asynchrone ?

L'apprentissage du JavaScript asynchrone est essentiel pour le développement Web moderne. Il vous permet de gérer efficacement des tâches telles que les requêtes API, en gardant vos applications réactives et rapides. La maîtrise des techniques asynchrones, telles que Promises et async/await, est cruciale non seulement pour créer des applications évolutives, mais également pour réussir les entretiens d'embauche JavaScript, où la compréhension de ces concepts est souvent un objectif clé. En maîtrisant le JavaScript asynchrone, vous améliorerez vos compétences en codage et vous préparerez mieux aux défis du monde réel.

Que sont les modèles asynchrones ?

Les modèles asynchrones en JavaScript sont des techniques utilisées pour gérer des tâches qui prennent du temps, comme la récupération de données sur un serveur, sans geler l'application. Initialement, les développeurs utilisaient des rappels pour gérer ces tâches, mais cette approche conduisait souvent à un code complexe et difficile à lire, appelé « l'enfer des rappels ». Pour simplifier cela, des promesses ont été introduites, offrant un moyen plus propre de gérer les opérations asynchrones en enchaînant les actions et en gérant les erreurs avec plus de grâce. L'évolution s'est poursuivie avec async/await, qui vous permet d'écrire du code asynchrone qui ressemble et se comporte davantage comme du code synchrone, ce qui le rend plus facile à lire et à maintenir. Ces modèles sont cruciaux pour créer des applications efficaces et réactives et sont fondamentaux dans le développement JavaScript moderne. Nous explorerons ces concepts plus en détail tout au long de ce blog.

qu'est-ce que le rappel ?

Les

Les rappels sont des fonctions que vous transmettez comme arguments à d'autres fonctions, avec l'intention que la fonction réceptrice exécute le rappel à un moment donné. Ceci est utile pour les scénarios dans lesquels vous souhaitez garantir qu'une partie du code s'exécute une fois qu'une tâche spécifique est terminée, comme après avoir récupéré des données sur un serveur ou terminé un calcul.

Comment fonctionnent les rappels :

  1. Vous définissez une fonction (callback).
  2. Vous passez cette fonction en argument à une autre fonction.
  3. La fonction de réception exécute le rappel au moment approprié.

exemple 1

function fetchData(callback) {
  // Simulate fetching data with a delay
  setTimeout(() => {
    const data = "Data fetched";
    callback(data); // Call the callback function with the fetched data
  }, 1000);
}

function processData(data) {
  console.log("Processing:", data);
}

fetchData(processData); // fetchData will call processData with the data

Copier après la connexion

exemple 2

// Function that adds two numbers and uses a callback to return the result
function addNumbers(a, b, callback) {
  const result = a + b;
  callback(result); // Call the callback function with the result
}

// Callback function to handle the result
function displayResult(result) {
  console.log("The result is:", result);
}

// Call addNumbers with the displayResult callback
addNumbers(5, 3, displayResult);

Copier après la connexion

Remarque : Je pense que les rappels sont efficaces pour gérer les opérations asynchrones, mais soyez prudent : à mesure que la complexité de votre code augmente, en particulier avec les rappels imbriqués, vous pouvez rencontrer un problème connu sous le nom d'enfer des rappels. Ce problème survient lorsque les rappels sont profondément imbriqués les uns dans les autres, entraînant des problèmes de lisibilité et rendant le code plus difficile à maintenir.

L'enfer des rappels

Callback Hell (également connu sous le nom de Pyramid of Doom) fait référence à la situation dans laquelle vous avez plusieurs rappels imbriqués. Cela se produit lorsque vous devez effectuer plusieurs opérations asynchrones en séquence et que chaque opération s'appuie sur la précédente.

ex. Cela crée une structure « pyramidale » qui peut être difficile à lire et à maintenir.

fetchData(function(data1) {
  processData1(data1, function(result1) {
    processData2(result1, function(result2) {
      processData3(result2, function(result3) {
        console.log("Final result:", result3);
      });
    });
  });
});

Copier après la connexion

Problèmes avec Callback Hell :

  1. Lisibilité : Le code devient difficile à lire et à comprendre.
  2. Maintenabilité : Apporter des modifications ou déboguer devient un défi.
  3. Gestion des erreurs : La gestion des erreurs peut devenir compliquée.

Gestion des erreurs avec les rappels

Lorsque vous travaillez avec des rappels, il est courant d'utiliser un modèle appelé rappels par erreur en premier. Dans ce modèle, la fonction de rappel prend une erreur comme premier argument. S'il n'y a pas d'erreur, le premier argument est généralement nul ou indéfini, et le résultat réel est fourni comme deuxième argument.

function fetchData(callback) {
  setTimeout(() => {
    const error = null; // Or `new Error("Some error occurred")` if there's an error
    const data = "Data fetched";
    callback(error, data); // Pass error and data to the callback
  }, 1000);
}

function processData(error, data) {
  if (error) {
    console.error("Error:", error);
    return;
  }
  console.log("Processing:", data);
}

fetchData(processData); // `processData` will handle both error and data

Copier après la connexion

Remarque : Après les rappels, des promesses ont été introduites pour gérer les processus asynchrones en JavaScript. Nous allons maintenant approfondir les promesses et explorer leur fonctionnement sous le capot.

Introduction aux promesses

Les

Les promesses sont des objets qui représentent l'achèvement (ou l'échec) éventuel d'une opération asynchrone et sa valeur résultante. Ils offrent un moyen plus propre de gérer le code asynchrone par rapport aux rappels.

Objectif des promesses :

  1. Avoid Callback Hell: Promises help manage multiple asynchronous operations without deep nesting.
  2. Improve Readability: Promises provide a more readable way to handle sequences of asynchronous tasks.

Promise States

A Promise can be in one of three states:

  1. Pending: The initial state, before the promise has been resolved or rejected.
  2. Fulfilled: The state when the operation completes successfully, and resolve has been called.
  3. Rejected: The state when the operation fails, and reject has been called.

Note: If you want to explore more, you should check out Understand How Promises Work Under the Hood where I discuss how promises work under the hood.

example 1

// Creating a new promise
const myPromise = new Promise((resolve, reject) => {
  const success = true; // Simulate success or failure
  if (success) {
    resolve("Operation successful!"); // If successful, call resolve
  } else {
    reject("Operation failed!"); // If failed, call reject
  }
});

// Using the promise
myPromise
  .then((message) => {
    console.log(message); // Handle the successful case
  })
  .catch((error) => {
    console.error(error); // Handle the error case
  });

Copier après la connexion

example 2

const examplePromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const success = Math.random() > 0.5; // Randomly succeed or fail
    if (success) {
      resolve("Success!");
    } else {
      reject("Failure.");
    }
  }, 1000);
});

console.log("Promise state: Pending...");

// To check the state, you would use `.then()` or `.catch()`
examplePromise
  .then((message) => {
    console.log("Promise state: Fulfilled");
    console.log(message);
  })
  .catch((error) => {
    console.log("Promise state: Rejected");
    console.error(error);
  });

Copier après la connexion

Chaining Promises

Chaining allows you to perform multiple asynchronous operations in sequence, with each step depending on the result of the previous one.

Chaining promises is a powerful feature of JavaScript that allows you to perform a sequence of asynchronous operations where each step depends on the result of the previous one. This approach is much cleaner and more readable compared to deeply nested callbacks.

How Promise Chaining Works

Promise chaining involves connecting multiple promises in a sequence. Each promise in the chain executes only after the previous promise is resolved, and the result of each promise can be passed to the next step in the chain.

function step1() {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Step 1 completed"), 1000);
  });
}

function step2(message) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(message + " -> Step 2 completed"), 1000);
  });
}

function step3(message) {
  return new Promise((resolve) => {
    setTimeout(() => resolve(message + " -> Step 3 completed"), 1000);
  });
}

// Chaining the promises
step1()
  .then(result => step2(result))
  .then(result => step3(result))
  .then(finalResult => console.log(finalResult))
  .catch(error => console.error("Error:", error));

Copier après la connexion

Disadvantages of Chaining:
While chaining promises improves readability compared to nested callbacks, it can still become unwieldy if the chain becomes too long or complex. This can lead to readability issues similar to those seen with callback hell.

Note: To address these challenges, async and await were introduced to provide an even more readable and straightforward way to handle asynchronous operations in JavaScript.

Introduction to Async/Await

async and await are keywords introduced in JavaScript to make handling asynchronous code more readable and easier to work with.

  • async: Marks a function as asynchronous. An async function always returns a promise, and it allows the use of await within it.
  • await: Pauses the execution of the async function until the promise resolves, making it easier to work with asynchronous results in a synchronous-like fashion.
async function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Data fetched");
    }, 1000);
  });
}

async function getData() {
  const data = await fetchData(); // Wait for fetchData to resolve
  console.log(data); // Logs "Data fetched"
}

getData();

Copier après la connexion

How Async/Await Works

1. Async Functions Always Return a Promise:

No matter what you return from an async function, it will always be wrapped in a promise. For example:

async function example() {
  return "Hello";
}

example().then(console.log); // Logs "Hello"

Copier après la connexion

Even though example() returns a string, it is automatically wrapped in a promise.

2. Await Pauses Execution:

The await keyword pauses the execution of an async function until the promise it is waiting for resolves.

async function example() {
  console.log("Start");
  const result = await new Promise((resolve) => {
    setTimeout(() => {
      resolve("Done");
    }, 1000);
  });
  console.log(result); // Logs "Done" after 1 second
}

example();

Copier après la connexion

In this example:

  • "Start" is logged immediately.
  • The await pauses execution until the promise resolves after 1 second.
  • "Done" is logged after the promise resolves.

Error Handling with Async/Await

Handling errors with async/await is done using try/catch blocks, which makes error handling more intuitive compared to promise chains.

async function fetchData() {
  throw new Error("Something went wrong!");
}

async function getData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error("Error:", error.message); // Logs "Error: Something went wrong!"
  }
}

getData();

Copier après la connexion

With Promises, you handle errors using .catch():

fetchData()
  .then(data => console.log(data))
  .catch(error => console.error("Error:", error.message));

Copier après la connexion

Using async/await with try/catch often results in cleaner and more readable code.

Combining Async/Await with Promises

You can use async/await with existing promise-based functions seamlessly.

example

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve("Data fetched");
    }, 1000);
  });
}

async function getData() {
  const data = await fetchData(); // Wait for the promise to resolve
  console.log(data); // Logs "Data fetched"
}

getData();

Copier après la connexion

Best Practices:

  1. Gunakan async/tunggu untuk kebolehbacaan: Apabila berurusan dengan berbilang operasi tak segerak, async/tunggu boleh menjadikan kod lebih linear dan lebih mudah difahami.
  2. Gabungkan dengan Janji: Teruskan menggunakan tak segerak/tunggu dengan fungsi berasaskan janji untuk mengendalikan aliran tak segerak yang kompleks dengan lebih semula jadi.
  3. Pengendalian Ralat: Sentiasa gunakan blok cuba/tangkap dalam fungsi async untuk mengendalikan kemungkinan ralat.

Kesimpulan

async and wait menyediakan cara yang lebih bersih dan mudah dibaca untuk mengendalikan operasi tak segerak berbanding dengan rantaian janji tradisional dan panggil balik. Dengan membenarkan anda menulis kod tak segerak yang kelihatan dan berkelakuan seperti kod segerak, ia memudahkan logik kompleks dan meningkatkan pengendalian ralat dengan blok cuba/tangkap. Menggunakan async/menunggu dengan janji menghasilkan kod yang lebih mudah diselenggara dan difahami.

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!

source:dev.to
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!