Quelles sont les fonctions asynchrones ES7?

J'ai utilisé Babel depuis un moment, et je l'aime. Cependant, sur la page d'accueil, où il répertorie les fonctionnalités prises en charge, il indique les Async functions .

J'ai fait beaucoup de Googling, et tout ce que je peux comprendre, c'est que c'est une fonctionnalité ES7.

Quelles sont les fonctions asynchrones ES7?

Async Attendez travailler avec ES6 Promesses. Vous pouvez les considérer comme un moyen d'écrire un code synchrone avec Promises.

Le mot-clé async marque comme méthode qui effectuera un appel asynchrone. Le mot clé await marque l'appel réel.

Avec une promesse, vous devez passer une méthode à la méthode .then() de la promesse de gérer le résultat.

 function doSomethingAsync() { return new Promise((resolve, reject) => { // call Rest service and resolve here }) } function printResult() { doSomethingAsync() .then(result => console.log(result)); } 

Tout cela fonctionne bien. Avec Async/Await nous pouvons écrire la dernière fonction un peu différente.

 async function printResult() { let result = await doSomethingAsync(); console.log(result); } 

L'avantage est que cela réduit simplement le besoin de rappels.

Pour plus d'informations: https://www.twilio.com/blog/2015/10/asyncawait-the-hero-javascript-deserved.html

ES2016 (communément appelé ES7 ou ECMAScript 7) est la prochaine évolution de la norme ECMA-262 (communément appelée JavaScript), et encore à un stade précoce.

Les fonctions asynchrones sont une nouvelle fonctionnalité JavaScript, proposée comme une partie de la norme ES2016 et qui n'est pas encore prise en charge par les navigateurs. Ils sont intégrés aux promesses .

Voir ci-dessous pour une introduction à cette nouvelle fonctionnalité à partir de diverses sources faisant autorité.

Remarque :

Même si les fonctions Async sont communément ES7 asynch functions (par exemple, pour les désambiguiser à partir d' async.js ou JavaScript asynchrone en général), Axel Rauschmayer recommande de ne pas les appeler , mais une fonctionnalité ne sera incluse que dans la prochaine norme Une fois que sa proposition a atteint la phase 4.

Les fonctions asynchrones ne sont qu'à l'étape 3 en ce moment. En fait, ES2016 ne contiendra probablement pas de fonctions asynchrones (comme Felix Kling l'a souligné dans les commentaires ci-dessous).


De la proposition de la phase 3 :

introduction

L'introduction de promesses et de générateurs dans ECMAScript offre une occasion d'améliorer considérablement le modèle de niveau de langue pour l'écriture de code asynchrone dans ECMAScript.

Une proposition semblable a été faite avec des fonctions reportées au cours des discussions ES6. La proposition ici prend en charge les mêmes cas d'utilisation, utilisant une syntaxe similaire ou identique, mais s'appuie directement sur des structures de flux de contrôle parallèles à celles des générateurs et utilise des promesses pour le type de retour, au lieu de définir des mécanismes personnalisés.

Le développement de cette proposition se produit à l' adresse https://github.com/tc39/ecmascript-asyncawait . Veuillez lister des problèmes là-bas. Les contributions non triviales sont limitées aux membres de TC39, mais les demandes de questions mineures sont les bienvenues et encouragées!

Statut de cette proposition

Cette proposition a été acceptée à l'étape 3 («Candidat») du processus de spécification ECMAScript en septembre 2015. Le champion souhaite que cette proposition soit acceptée à l'étape 4 («Terminé») d'ici la fin de novembre.

Exemples

Prenez l'exemple suivant, d'abord écrit en utilisant Promises. Ce code encadre un ensemble d'animations sur un élément, s'arrête lorsqu'il y a une exception dans une animation et renvoie la valeur produite par l'animation finale réussie.

 function chainAnimationsPromise(elem, animations) { let ret = null; let p = currentPromise; for(const anim of animations) { p = p.then(function(val) { ret = val; return anim(elem); }) } return p.catch(function(e) { /* ignore and keep going */ }).then(function() { return ret; }); } 

Déjà avec des promesses, le code est beaucoup amélioré à partir d'un style de rappel direct, où ce type de boucle et la gestion des exceptions sont difficiles.

Task.js et les bibliothèques similaires offrent un moyen d'utiliser les générateurs pour simplifier davantage le code en maintenant la même signification:

 function chainAnimationsGenerator(elem, animations) { return spawn(function*() { let ret = null; try { for(const anim of animations) { ret = yield anim(elem); } } catch(e) { /* ignore and keep going */ } return ret; }); } 

Il s'agit d'une amélioration marquée. Tout le projet de loi évoqué au-delà du contenu sémantique du code est supprimé et le corps de la fonction interne représente l'intention de l'utilisateur. Cependant, il existe une couche extérieure d'étiquette pour envelopper le code dans une fonction de générateur supplémentaire et la transmettre à une bibliothèque pour se convertir à une promesse. Cette couche doit être répétée dans chaque fonction qui utilise ce mécanisme pour produire une promesse. Ceci est tellement courant dans le code typique de Javascript asynchrone, qu'il est utile de supprimer la nécessité de l'étiquette restante.

Avec les fonctions asynchrones, tout le gabarit restant est supprimé, laissant uniquement le code sémantiquement significatif dans le texte du programme:

 async function chainAnimationsAsync(elem, animations) { let ret = null; try { for(const anim of animations) { ret = await anim(elem); } } catch(e) { /* ignore and keep going */ } return ret; } 

Des fonctions asynchrones ES7 d' article de Jake Archibald :

Async avec des promesses

Dans l' article HTML5Rocks sur les promesses , l'exemple final montre comment charger des données JSON pour une histoire, puis l'utiliser pour récupérer plus de données JSON pour les chapitres, puis rendre les chapitres en ordre dès leur arrivée.

Le code ressemble à ceci:

 function loadStory() { return getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); return story.chapterURLs.map(getJSON) .reduce(function(chain, chapterPromise) { return chain.then(function() { return chapterPromise; }).then(function(chapter) { addHtmlToPage(chapter.html); }); }, Promise.resolve()); }).then(function() { addTextToPage("All done"); }).catch(function(err) { addTextToPage("Argh, broken: " + err.message); }).then(function() { document.querySelector('.spinner').style.display = 'none'; }); } 

Pas mal, mais …

Cette fois avec les fonctions asynchrones ES7 …

 async function loadStory() { try { let story = await getJSON('story.json'); addHtmlToPage(story.heading); for (let chapter of story.chapterURLs.map(getJSON)) { addHtmlToPage((await chapter).html); } addTextToPage("All done"); } catch (err) { addTextToPage("Argh, broken: " + err.message); } document.querySelector('.spinner').style.display = 'none'; } 

Avec des fonctions asynchrones ( proposition complète ), vous pouvez await une promesse. Cela arrête la fonction de manière non bloquante, attend la promesse de résoudre et renvoie la valeur. Si la promesse rejette, elle jette avec la valeur de rejet, afin que vous puissiez l'utiliser à l'aide de la catch .

Edit: J'ai été utilisé à l'origine dans une fonction de flèche, apparemment ce n'est pas autorisé, donc je l'ai remplacé par une boucle for . Domenic m'a donné un aperçu de la connaissance de pourquoi await ne peut pas être utilisé dans les fonctions de flèche .

loadStory renvoie une promesse, de sorte que vous pouvez l'utiliser dans d'autres fonctions asynchrones.

 (async function() { await loadStory(); console.log("Yey, story successfully loaded!"); }()); 

De KoaJS article L'évolution du JavaScript asynchrone :

Générateur / rendement

Les générateurs JavaScript sont un concept relativement nouveau, ils ont été introduits dans ES6 (également connu sous le nom de ES2015).

Ne serait-il pas agréable que, lorsque vous exécutez votre fonction, vous pouvez l'arrêter à n'importe quel moment, calculer autre chose, faire d'autres choses, puis revenir sur elle, même avec une certaine valeur et continuer?

C'est exactement ce que les fonctions de générateur font pour vous. Lorsque nous appelons une fonction de générateur, il ne démarre pas, nous devrons l'itérer manuellement.

 function* foo () { var index = 0; while (index < 2) { yield index++; } } var bar = foo(); console.log(bar.next()); // { value: 0, done: false } console.log(bar.next()); // { value: 1, done: false } console.log(bar.next()); // { value: undefined, done: true } 

Si vous souhaitez utiliser facilement des génératrices pour l'écriture de JavaScript asynchrone, vous aurez besoin de co .

Co est une génératrice basée sur le contrôle de la qualité du flux pour Node.js et le navigateur, en utilisant des promesses, vous permettant d'écrire un code non bloquant de manière agréable.

Avec co , nos exemples précédents peuvent ressembler à ceci:

 co(function* (){ yield Something.save(); }).then(function() { // success }) .catch(function(err) { //error handling }); 

Vous pouvez demander: et les opérations en parallèle? La réponse est plus simple que vous ne le pensez ( sous les capots, c'est juste une Promise.all ):

 yield [Something.save(), Otherthing.save()]; 

Async / attend

Les fonctions asynchrones ont été introduites dans ES7 – et actuellement disponibles uniquement à l'aide d'un transpiler comme babel. (Disclaimer: maintenant nous parlons du mot clé asynchrone, pas du package asynchrone)

En bref, avec le mot clé async nous pouvons faire ce que nous faisons avec la combinaison de co et de générateurs – sauf le piratage.

Entrez la description de l'image ici

Sous les fonctions async l'aide de Promises – c'est pourquoi la fonction asynchique revient avec une Promise .