Async et Attendent expliqué avec des dessins et des exemples

brève introduction

JavaScript ES7 dans la promesse async / vous attendent pour faire de multiples collaboration asynchrone plus facile à travailler ensemble. Si, selon un certain ordre pour obtenir des données à partir de plusieurs bases de données ou API asynchrone, vous pourriez jouer avec un tas de promesses et d'une fonction de rappel terminée. Le async / Attendent let structure nous utilisons un code lisible, maintenable plus succinctement permet cette logique.

Cet exemple simple tutoriel d'un graphique et expliqué en JavaScript async / Attendent syntaxe et la sémantique.

Avant de plonger dans, le bref rappel de la promesse let. Si vous connaissez déjà la promesse de JS, vous pouvez sauter cette section.

promesses

En JavaScript, la promesse au nom de la non-blocage de l'exécution asynchrone d'abstraction. Si vous connaissez Java Future, C # la tâche, vous constaterez que promettent beaucoup comme eux.

Promise pour le réseau général et des opérations d'E / S, telles que la lecture du fichier, ou de créer des requêtes HTTP. Nous pouvons créer une promesse asynchrone, puis ensuite ajouter une fonction de rappel, lorsque la fin de la promesse déclenchera la fonction de rappel, et le non-blocage de courant sous tension « fil. » La fonction de rappel lui-même peut également renvoyer un objet de la promesse, afin que nous puissions appeler la promesse de la chaîne.

Par souci de simplicité, nous supposons que tous les exemples suivants ont été installés et la bibliothèque demande-promesse chargée comme ceci:

= Var rp besoin ( 'demande-promesse');

Maintenant, nous pouvons créer un objet de promesse de retour comme simple requête HTTP GET:

const promesse = rp ( '

Nous attendons maintenant un exemple:

console.log ( 'Démarrage exécution');

const promesse = rp ( '

promise.then (résultat = >  console.log (suite));

console.log ( « Peut sais pas si la promesse n'a pas encore fini ... »);

Nous avons créé un objet de promesse sur la ligne 3, ligne 4, pour lui donner ajouté une fonction de rappel. Promesse est asynchrone, lorsque la mise en uvre de la sixième ligne, nous ne savons pas si la promesse a été achevée. Si cette section de code exécuter plusieurs fois, vous pouvez obtenir des résultats différents à chaque fois. D'une manière générale, qui est la promesse et la promesse de créer un code qui est en cours d'exécution simultanément.

Jusqu'à promesse exécutée, seule façon de bloquer la séquence actuelle des opérations. Cela diffère de la Future.get de Java, il nous permet de bloquer le thread courant avant la fin de l'avenir. Pour JavaScript, nous ne pouvons pas attendre la promesse exécutée. Dans la méthode de la promesse est à l'origine du code de programme ajouté à par la fonction de rappel alors.

Le présent mode de réalisation est décrit dans la figure processus de calcul:

Promesse de calcul. « Discussion » est en cours d'exécution ne peut pas attendre la promesse d'achever la mise en uvre. Dans la méthode de la promesse est à l'origine du code de programme ajouté à par la fonction de rappel alors.

Par puis ajouter la fonction de rappel avec succès que si la promesse sera réalisée. Si elle échoue (par exemple en raison d'une erreur de réseau), la fonction de rappel ne sera pas exécutée. Vous pouvez attraper puis ajouter une fonction de rappel pour gérer la promesse a échoué:

rp ( '

 puis (() = >  console.log ( 'succès')).

 = De capture (e >  console.log ( `a échoué: $ {e}`))

Enfin, pour tester, nous pouvons utiliser Promise.resolve Promise.reject facilement créer et exécuter le succès ou l'échec de la promesse « fou »:

const = succès Promise.resolve ( 'Résolu');

// print « Résultat réussi: Résolu »

succès.

 puis (résultat = >  console.log ( `résultat avec succès: $ {résultat}`)).

 = De capture (e >  console.log ( `a échoué avec: $ {e}`))

const = Promise.reject sûr ( 'Err');

// print "Échec avec: Err"

échec.

 puis (résultat = >  console.log ( `résultat avec succès: $ {résultat}`)).

 = De capture (e >  console.log ( `a échoué avec: $ {e}`))

Pour un tutoriel promesse plus détaillé, vous pouvez vous référer à cet article.

La question est - une combinaison de promesses

Une seule promesse très facile à obtenir. Cependant, lorsque le temps nécessaire pour la programmation complexe logique asynchrone, nous sommes susceptibles de durer un certain temps avec la promesse de plusieurs objets. Ensuite, écrivez un tas de déclarations et de rappel anonyme facilement rendu difficile à contrôler.

Par exemple, supposons que nous devons résoudre les exigences du programme suivant:

Créer requête HTTP, dans l'attente des demandes et imprimer le résultat final;

Créer deux requêtes HTTP parallèles;

Après que les deux demandes, etc., d'imprimer les résultats.

Le code suivant montre comment résoudre ce problème:

// premier appel

const call1Promise = rp ( '

call1Promise.then (result1 = >  {

 // La première demande est terminée est exécutée

 console.log (result1);

 const call2Promise = rp ( '

 const call3Promise = rp ( '

 retour Promise.all ( );

}). Ensuite (arr = >  {

 // Après deux promesse interprétera les deux extrémités

 console.log (arr );

 console.log (arr );

})

Nous commençons à créer la première requête HTTP, et ajouté un temps d'exécution de rappel d'achèvement (lignes 1-3). Dans la fonction de rappel, nous créons deux promesses supplémentaires (8-9 lignes) pour les demandes ultérieures HTTP. Les deux promettent en même temps pour effectuer, et nous devons être en mesure d'ajouter une fonction de rappel après avoir terminé l'exécution. Nous avons donc besoin Promise.all les combiner en une seule promesse (ligne 11), après avoir mis fin à cette promesse est terminée. Ceci est une promesse de retourner l'objet de rappel, donc nous avons besoin d'ajouter une fonction de rappel, puis imprimer le résultat (lignes 12-16).

Le schéma suivant illustre le processus de calcul:

Promise combinaison processus de calcul. Nous utiliserons deux Promise.all promesse parallèle combinée à une promesse.

Pour cet exemple simple, nous avons passé les deux dernières méthode, puis le rappel, et a dû utiliser Promise.all pour faire deux promesse parallèle simultanément. Si nous devons effectuer une opération plus asynchrone, ou ajouter la gestion des erreurs ce qui se passera? Cette dernière méthode peut facilement conduire à un tas d'ordures puis, Promise.all et callbacks.

méthode async

Async est un moyen rapide de définir la fonction de la promesse de retour cible.

Par exemple, les deux définitions suivantes sont équivalentes:

la fonction f () {

 retourner Promise.resolve ( 'TEST');

}

// asyncF et f sont équivalentes

async fonction asyncF () {

 retour 'TEST';

}

De même, la méthode async jette un retour d'exception est équivalente à la méthode de promesse de rejet:

la fonction f () {

 retourner Promise.reject ( 'Erreur');

}

// asyncF et f sont équivalentes

async fonction asyncF () {

 jeter « Erreur »;

}

Attendent

Nous avons créé la promesse, mais ne peut pas attendre pour effectuer une synchronisation complète. Nous ne pouvons passer une fonction de rappel alors. Nous ne sommes pas autorisés à attendre la promesse d'encourager le développement du code non-bloquant. Dans le cas contraire, les développeurs ne pouvaient pas toujours effectuer des opérations de blocage, car il est plus simple que d'utiliser la promesse et callbacks.

Toutefois, afin de synchroniser la promesse d'exécution, nous devons les amener à attendre la fin de l'autre. En d'autres termes, si une opération est asynchrone (à savoir, encapsulé dans la promesse), il devrait être en mesure d'attendre une autre opération asynchrone exécutée. Mais l'interpréteur JavaScript pour savoir comment l'opération est en cours d'exécution dans une promesse en elle?

La réponse se trouve dans le mot-clé. Async Chaque méthode async retourne un objet de promesse. Par conséquent, interpréteur JavaScript pour comprendre le fonctionnement de toutes les méthodes async sont encapsulés dans la promesse de l'exécution asynchrone. Par conséquent interprète pour leur permettre d'attendre que d'autres promesses d'exécution.

Attendre la mise en mots-clés suivants. Il ne peut être utilisé dans la méthode async, afin que nous puissions attendre la promesse de synchronisation exécutée. Si vous utilisez la promesse en dehors de la fonction async, alors nous avons encore besoin d'utiliser une fonction de rappel:

async fonction f () {

 // réponse est la valeur de la mise en uvre réussie de la promesse

 réponse const = await rp ( '

 console.log (réponse);

}

// méthode async ne peut pas être utilisé sévissent à l'extérieur

// fonction de rappel est nécessaire, alors ......

f (). puis (() = >  console.log ( 'fini'));

Maintenant, nous regardons comment résoudre le problème sur l'un des:

// La solution est encapsulée dans la fonction async

solution de fonction asynchrone () {

 // attente pour la première requête HTTP et imprimer les résultats

 console.log (await rp ( '

 // Créer deux requêtes HTTP, allant de leur exécution complète - en même temps leur permettent d'effectuer

 const call2Promise = rp ( ' // N'attend pas!

 const call3Promise = rp ( ' // N'attend pas!

 // Une fois que vous avez créé - en attente pour eux d'effectuer complète

 const response2 = await call2Promise;

 const réponse3 = await call3Promise;

 console.log (response2);

 console.log (réponse3);

}

// appel de cette fonction async

solution (). puis (() = >  console.log ( 'fini'));

Dans le code ci-dessus, la solution que nous encapsulé dans la fonction async. Cela nous permet d'utiliser le mot-clé await directement à l'intérieur de la promesse, alors il n'y a pas besoin d'utiliser une fonction de rappel. Enfin, appelez async cette fonction, il crée simplement un objet de la promesse, et cette promesse encapsule les appels vers d'autres promesses de la logique.

Bien sûr, dans le premier exemple (sans async / Attendent), la promesse deux sont déclenchées simultanément. Ce code est le même (lignes 7-8). Notez que jusqu'à la ligne 11-12, nous utilisons await, le programme a été bloqué pour compléter les deux promesse d'exécuter. Ensuite, nous pouvons conclure que les deux cas sont la mise en uvre réussie de la promesse (et l'utilisation Promise.all (...) .alors (...) similaire).

Continuez le processus de calcul derrière cela est à peu près égale à une donnée. Mais le code plus lisible et plus facile à comprendre.

En fait, async / vous attendent au bas de la promesse, puis convertie en une fonction de rappel. En d'autres termes, il est la promesse d'utiliser le sucre de syntaxe. Chaque fois que nous utilisons await, l'interprète crée un objet promesse et puis utiliser le reste de la fonction async en place alors la fonction de rappel.

Regardons l'exemple suivant:

async fonction f () {

 console.log ( 'A partir F');

 résultat const = await rp ( '

 console.log (résultat);

}

On nous donne ci-dessous fonction f processus de calcul sous-jacent. Puisque f est async, il sera exécuté en même temps que l'appelant dit:

Attendre le processus de calcul.

La fonction f exécute et crée un objet promesse. A ce moment, les pièces de fonction restantes sont encapsulées dans une fonction de rappel, et exécutés après la promesse.

Gestion des erreurs

La plupart de l'exemple précédent, nous supposons que cette promesse exécutée avec succès. Par conséquent attendre la valeur de retour sur la promesse. Si nous promettons await a échoué, sauf la fonction async se produit. Nous pouvons utiliser un try / catch standard pour gérer cette situation:

async fonction f () {

 try {

 const promiseResult = await Promise.reject ( 'Erreur');

 } Catch (e) {

 console.log (e);

 }

}

fonction Async ne gère pas l'exception, aucune anomalie de la matière sont causées par le refus de la promesse ou tout autre bug, et il retournera une promesse de refus:

async fonction f () {

 // Renvoie une exception

 const promiseResult = await Promise.reject ( 'Erreur');

}

// Affichera « Erreur »

f ().

 puis (() = >  console.log ( 'succès')).

 catch (err = >  console.log (err))

async fonction g () {

 jeter « Erreur »;

}

// Affichera « Erreur »

g ().

 puis (() = >  console.log ( 'succès')).

 catch (err = >  console.log (err))

discuter

Async / promesse await est de rendre la langue de la structure plus parfaite. Il nous permet d'utiliser moins de code en utilisant la promesse. Cependant, async / Attendent n'a pas remplacé la promesse ordinaire. Par exemple, si l'appel de fonction ou de synchronisation dans une fonction ordinaire au niveau mondial, nous avons aucun moyen que d'utiliser await dépend de la promesse générale :

async fonction FASYNC () {

 // valeur de retour réelle est Promise.resolve (5)

 retour 5;

}

// ne peut pas appeler "await FASYNC ()". Besoin d'utiliser alors / catch

FASYNC (). puis (r = >  console.log ( `résultat est $ {r}`));

Je généralement la logique la plus asynchrone encapsulés dans une ou plusieurs fonctions async, puis appeler le code non-asynchrone. Il me fait écrire aussi peu que possible try / catch rappel.

la structure Async / await est de promettre d'utiliser le sucre de syntaxe plus concise de. Chaque structure async / Attendent peut être écrit comme promesse ordinaire. En fin de compte, il est un style de codage et des questions concises.

Remarques sur les informations différenciées concurrence et parallélisme, vous pouvez vérifier la discussion Rob Pike sur cette question ou mon article. Concurrency fait référence au processus indépendant (processus dans le sens habituel) de travailler ensemble, et parallèle moyenne, vraiment gérer plusieurs tâches simultanément. En même temps se rapportant à la conception d'applications et l'architecture, et parallèlement à l'exécution réelle.

Nous prenons une application multi-thread par exemple. Applications séparées dans son modèle de fil clair concurrency. Ces fils mappés sur les noyaux disponibles ou définit son parallélisme de niveau. système concurrent peut fonctionner efficacement sur un seul processeur, auquel cas, il n'est pas parallèle.

VS simultané en parallèle

En ce sens, nous nous engageons pour que nous puissions être décomposées en modules de programme simultanés qui peuvent ou peuvent ne pas être exécutées en parallèle. Aucune Javascript effectuée réelle en parallèle en fonction de la mise en uvre particulière. Par exemple, le nud JS est mono-thread, il n'y aurait aucune promesse si le traitement parallèle est intensive informatiquement (CPU liée). Cependant, si vous utilisez quelque chose comme Nashorn le code Java en code binaire, il peut être calculé théoriquement possible promesse intensive mis en correspondance avec différents curs de processeurs pour atteindre parallélisation. Donc, je pense, la promesse (générale ou avec le async / Attendent a) la composition du bloc concurrent applications JavaScript.

Expédition a marqué le début deux grandes ligne principale positif prêt à voler
Précédent
LOL dernière course sur les singles costume fraîche recommande Paode sauvages tels atours pour être sûr!
Prochain
150000 yuans recommandation personnalisée SUV ne sont pas les mêmes que les modèles de la jeunesse
L'élection de Merkel se rapproche cassé sa bien-aimée voiture allemande
gamme complète de Toyota prendre la technologie de sécurité active, Yan Zhi valeur Bin beau grand cercle frit, 130000 zayang domestiques
Replay limite quotidienne - l'armée tant attendue
La concurrence sur le marché pour mettre à niveau, Honda a présenté deux 650cc « Titans » pour faire face au changement
couronne de ventes mensuelles ne répond pas et faire les choses, par 1,3T, 7 Wanduo laisser GS4 comment faire
contre tout assassin de mêlée! LOL jouer la nouvelle version de Kali enseignement de routine
Présentez une semaine | pour voir le plus beau timbre, le goût de peindre jusqu'à une histoire d'amour demi-siècle
Longue 5 Mi atmosphère Cour Biya, avec une grille intelligente toit ouvrant panoramique, avec le joint-venture pour acheter de la haute Magotan
BA et BBA dans les nouveaux modèles ont plus d'enfants un bon combat que vous devinez quelle voiture?
LOL Pourquoi toujours jouer lose bouc émissaire sur le terrain de jeu? Inventaire LPL ancien homme bouc émissaire
Le stock après le disque principal de contrôle « effondrement flash » de l'extrême rencontré, quatre limite après une forte reprise!