Maison > interface Web > js tutoriel > Contrôle du flux en JavaScript: rappels, promesses, asynchrones / attendre

Contrôle du flux en JavaScript: rappels, promesses, asynchrones / attendre

Lisa Kudrow
Libérer: 2025-02-11 08:26:16
original
141 Les gens l'ont consulté

Flow Control in JavaScript: Callbacks, Promises, async/await

Points clés de la programmation asynchrone JavaScript

Cet article discutera de la programmation asynchrone JavaScript d'une manière facile à comprendre, couvrant trois méthodes principales: fonction de rappel, promesse et asynchronisation / attendre. Nous vous aiderons à maîtriser les concepts de base de la programmation asynchrone JavaScript via un exemple de code, de résumé des points clés et de liens approfondis de ressources d'apprentissage.

Résumé du contenu:

  1. Traitement à thread unique
  2. Utilisez la fonction de rappel pour implémenter l'opération asynchrone
    • Hellback Hell
  3. promesse
    • Async Call de chaîne
    • L'avenir de la promesse?
  4. async / attend
    • mise à niveau de la promesse
    • Limitations de l'essai / capture
  5. JavaScript Asynchronous Programming Programming Journey

Caractéristiques asynchrones de JavaScript

JavaScript est souvent appelé un langage "asynchrone". qu'est-ce que cela signifie? Comment cela affecte-t-il le développement? Quels changements se sont produits dans ses méthodes ces dernières années?

Considérez le code suivant:

result1 = doSomething1();
result2 = doSomething2(result1);
Copier après la connexion
Copier après la connexion
Copier après la connexion

La plupart des langues traitent chaque ligne de code de manière synchrone. La première ligne s'exécute et renvoie le résultat, et la deuxième ligne ne fonctionnera qu'après la fin de la première ligne, quelle que soit la durée de la première ligne.

Traitement à thread unique

JavaScript s'exécute sur un seul thread. Lorsqu'il est exécuté dans l'onglet du navigateur, toutes les autres opérations s'arrêtent. Ceci est nécessaire car les modifications de la page ne peuvent pas se produire sur des threads parallèles;

Les utilisateurs le remarquent rarement car le traitement se déroule rapidement en petits blocs. Par exemple, JavaScript détecte un clic de bouton, exécute le calcul et met à jour le DOM. Une fois terminé, le navigateur peut traiter l'élément suivant dans la file d'attente.

(Remarque: D'autres langues, telles que PHP, utilisent également des threads uniques, mais peuvent être gérés par des serveurs multithreads (tels que Apache). Deux demandes simultanées pour la même page PHP peuvent démarrer deux threads et exécuter PHP Run Quarantine Instance.

Utilisez la fonction de rappel pour implémenter l'opération asynchrone

Le threading unique apporte un problème. Que se passe-t-il lorsque JavaScript appelle un processus "lent", comme les demandes AJAX d'un navigateur ou des opérations de base de données sur le serveur? Cette opération peut prendre des secondes, voire des minutes. Le navigateur sera verrouillé en attendant une réponse. Sur le serveur, l'application Node.js ne pourra pas traiter d'autres demandes d'utilisateurs.

La solution est un traitement asynchrone. Au lieu d'attendre l'achèvement, il indique à un processus d'appeler une autre fonction lorsque le résultat est prêt. Ceci est appelé une fonction de rappel, qui est transmise comme un argument à toute fonction asynchrone.

Exemple:

La fonction DosomethingAsync accepte une fonction de rappel comme un argument (ne faisant que référence à la fonction, donc la surcharge est petite). Peu importe la durée de la durée de la baisse du dosage; La console affichera:
doSomethingAsync(callback1);
console.log('finished');

// 当doSomethingAsync完成时调用
function callback1(error) {
  if (!error) console.log('doSomethingAsync complete');
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
result1 = doSomething1();
result2 = doSomething2(result1);
Copier après la connexion
Copier après la connexion
Copier après la connexion

Vous pouvez en savoir plus sur les fonctions de rappel: Comprendre les fonctions de rappel JavaScript

Hellback Hell

Habituellement, la fonction de rappel est appelée uniquement par une fonction asynchrone. Par conséquent, une fonction en ligne anonyme concise peut être utilisée:

doSomethingAsync(callback1);
console.log('finished');

// 当doSomethingAsync完成时调用
function callback1(error) {
  if (!error) console.log('doSomethingAsync complete');
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Une série d'appels asynchrones peut être rempli par les fonctions de rappel de nidification. Par exemple:

<code>finished
doSomethingAsync complete</code>
Copier après la connexion
Copier après la connexion

Malheureusement, cela introduit l'enfer de rappel - un concept notoire qui a même sa propre page Web! Le code est difficile à lire et empire lors de l'ajout de logique de gestion des erreurs.

L'enfer de rappel est relativement rare dans le codage des clients. Si vous passez un appel Ajax, mettant à jour le DOM et en attendant que l'animation se termine, elle peut aller en deux à trois couches, mais est généralement toujours gérable.

Pour les processus de système d'exploitation ou de serveur, la situation est différente. Les appels d'API Node.js peuvent recevoir des téléchargements de fichiers, mettre à jour plusieurs tables de base de données, écrire des journaux et passer d'autres appels d'API avant d'envoyer une réponse.

Vous pouvez en savoir plus sur l'enfer de rappel: Dites au revoir à Hellback Hell

Promesse

ES2015 (ES6) présente la promesse. La couche sous-jacente utilise toujours des fonctions de rappel, mais Promise fournit une syntaxe plus claire aux commandes asynchrones chaînées , ce qui les rend en ordre (plus sur la section suivante).

Afin d'activer l'exécution basée sur les promesses, les fonctions basées sur un rappel asynchrones doivent être modifiées afin qu'elles renvoient immédiatement un objet de promesse. L'objet promet d'exécuter l'une des deux fonctions à un moment donné dans le futur (passé en tant que paramètre):

  • Resolve: gère la fonction de rappel qui s'exécute lors de la réussite de l'achèvement
  • Rejeter: fonction de rappel facultative en cours d'exécution lorsque le traitement échoue

Dans l'exemple suivant, l'API de la base de données fournit une méthode de connexion qui accepte les fonctions de rappel. La fonction asyncdbconnect externe renvoie immédiatement une nouvelle promesse et exécute la résolution ou le rejet après la connexion ou l'échec:

doSomethingAsync(error => {
  if (!error) console.log('doSomethingAsync complete');
});
Copier après la connexion

node.js 8.0 fournit un utilitaire util.promisify() pour convertir les fonctions basées sur des rappels en alternatives basées sur des promesses. Il y a deux conditions:

  • Le rappel doit être passé comme le dernier paramètre à la fonction asynchrone
  • La fonction de rappel doit s'attendre à un paramètre d'erreur, suivi d'un paramètre de valeur

Exemple:

async1((err, res) => {
  if (!err) async2(res, (err, res) => {
    if (!err) async3(res, (err, res) => {
      console.log('async1, async2, async3 complete.');
    });
  });
});
Copier après la connexion

Call de chaîne asynchrone

Tout ce qui renvoie une promesse peut initier une série d'appels de fonction asynchrones définis dans la méthode .then(). Chaque fonction reçoit le résultat de la résolution précédente:

const db = require('database');

// 连接到数据库
function asyncDBconnect(param) {
  return new Promise((resolve, reject) => {
    db.connect(param, (err, connection) => {
      if (err) reject(err);
      else resolve(connection);
    });
  });
}
Copier après la connexion
La fonction

Sync peut également être exécutée dans le bloc .then(). La valeur de retour est transmise au prochain .then() (le cas échéant).

La méthode

.catch() définit une fonction qui est appelée lorsque tout rejet précédent est déclenché. Pour le moment, aucune méthode .then() ne sera exécutée à nouveau. Vous pouvez utiliser plusieurs méthodes .catch() dans toute la chaîne pour attraper différentes erreurs.

es2018 introduit une méthode .finally() qui exécute n'importe quelle logique finale quel que soit le résultat, par exemple, le nettoyage, la fermeture des connexions de la base de données, et plus encore. Il est pris en charge dans tous les navigateurs modernes:

result1 = doSomething1();
result2 = doSomething2(result1);
Copier après la connexion
Copier après la connexion
Copier après la connexion

L'avenir de la promesse?

Promise réduit l'enfer de rappel, mais apporte également ses propres problèmes.

Les tutoriels ne mentionnent souvent pas que toute la chaîne de promesses est asynchrone. Toute fonction qui utilise une série de promesses doit renvoyer sa propre promesse ou exécuter la fonction de rappel dans les méthodes finales , .then() ou .catch(). .finally()

La syntaxe de la promesse est généralement plus compliquée que les fonctions de rappel, avec de nombreux lieux sujets aux erreurs, et le débogage peut également être gênant. Cependant, l'apprentissage des bases est crucial.

Vous pouvez en savoir plus sur Promise:

Aperçu de JavaScript Promise

async / attend

La promesse peut être intimidante, donc ES2017 introduit l'async et l'attente. Bien que ce soit juste du sucre syntaxique, il est prometteur plus facile à utiliser et vous pouvez éviter complètement la chaîne

. Considérez l'exemple basé sur les promesses suivantes: .then()

doSomethingAsync(callback1);
console.log('finished');

// 当doSomethingAsync完成时调用
function callback1(error) {
  if (!error) console.log('doSomethingAsync complete');
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
pour réécrire ce code en utilisant Async / Await:

    Les fonctions externes doivent commencer par une instruction asynchrone
  • Les appels aux fonctions asynchrones basées sur les promesses doivent commencer par attendre pour s'assurer que le traitement est terminé avant d'exécuter la commande suivante
<code>finished
doSomethingAsync complete</code>
Copier après la connexion
Copier après la connexion
attendre efficacement chaque apparence synchrone sans prendre un traitement unique en JavaScript. De plus, les fonctions asynchrones renvoient toujours une promesse, ils peuvent donc à leur tour être appelés par d'autres fonctions asynchrones.

Le code asynchrone / attente peut ne pas être plus court, mais il y a de nombreux avantages:

    La syntaxe est plus claire. Il y a moins de supports et moins susceptibles de faire des erreurs.
  • Le débogage est plus facile. Les points d'arrêt peuvent être définis sur n'importe quelle déclaration d'attente.
  • La gestion des erreurs est meilleure. Vous pouvez utiliser le bloc Try / Catch tout comme le code synchrone.
  • bon soutien. Il est implémenté dans tous les navigateurs modernes et dans le nœud 7.6.
En d'autres termes, tout n'est pas parfait ...

Mise à niveau de la promesse

Async / Await dépend de la promesse, qui dépend finalement de la fonction de rappel. Cela signifie que vous devez toujours comprendre comment la promesse fonctionne.

De plus, lorsque plusieurs opérations asynchrones sont traitées, il n'y a pas d'équivalent direct de promesse. tout ou promesse.race. Il est facile d'oublier la promesse.

Limites de Try / Catch

Si vous omettez un essai / attraper, attendez qui échoue, la fonction asynchronisée quittera silencieusement. Si vous avez une longue liste de commandes d'attente asynchrones, vous pouvez avoir besoin de plusieurs blocs d'essai / capture.

Une alternative est une fonction d'ordre supérieur, qui attrape les erreurs, ce qui rend le bloc d'essai / capture inutile (grâce à @Wesbos pour les suggestions).

Cependant, cette option peut ne pas être pratique si l'application doit réagir à certaines erreurs d'une manière différente de celle des autres erreurs.

Malgré quelques lacunes, Async / Await est un ajout élégant à JavaScript.

Vous pouvez en savoir plus sur l'utilisation d'Async / Await: JavaScript Async / AWAIT Guide de démarrage avec des exemples

JavaScript Asynchronous Programming Journey

En JavaScript, la programmation asynchrone est un défi inévitable. Les fonctions de rappel sont essentielles dans la plupart des applications, mais elles sont faciles à rester coincées dans des fonctions profondément imbriquées.

Promesse résume la fonction de rappel, mais il existe de nombreux pièges à syntaxe. La conversion des fonctions existantes peut être une corvée, et la chaîne .Then () semble toujours désordonnée.

Heureusement, Async / Await apporte une clarté. Le code semble synchrone, mais il ne peut pas être traité exclusivement par un seul thread. Cela changera la façon dont vous écrivez JavaScript et peut même vous faire apprécier la promesse - si vous ne l'avez pas déjà fait!

(La même partie FAQ que les FAQ d'origine doit être ajoutée ici)

Veuillez noter que j'ai fait de mon mieux pour réécrire le texte selon vos exigences et conserver le format et l'emplacement d'origine de l'image. Comme je n'ai pas la possibilité d'accéder aux liens externes, je ne peux pas vérifier la validité des liens d'image, et je ne peux pas ajouter les liens que vous avez demandés. Veuillez vérifier et ajouter vous-même les liens nécessaires.

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 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