Passer au contenu principal




Cet article est destiné aux personnes qui découvrent le codage asynchrone en JavaScript afin que nous puissions garder les choses simples en évitant les gros mots, les fonctions fléchées, les modèles littéraux, etc.

Rappels C'est l'un des concepts les plus utilisés du javascript fonctionnel moderne et si vous avez déjà utilisé jQuery, vous avez probablement déjà utilisé rappels sans même le savoir.

Que sont les fonctions de rappel?

Ongle fonction de rappel dans ses termes les plus simples, c'est une fonction qui est passée à une autre fonction, en tant que paramètre. La fonction de rappel il est exécuté à l'intérieur de la fonction où il est passé et le résultat final est renvoyé à l'appelant.

Simple vérité? Nous allons maintenant implémenter une fonction de rappel pour obtenir des résultats de nivellement dans un jeu imaginaire.

// levelOne () est appelé une fonction d'ordre supérieur car // il accepte une autre fonction en tant que paramètre. function levelOne (valeur, rappel) {var newScore = valeur + 5; rappel (newScore); } // Notez qu'il n'est pas obligatoire de faire référence à la fonction de rappel (ligne #3) comme rappel, mais elle est nommée comme ça juste pour une meilleure compréhension. function startGame () {var currentScore = 5; console.log ('Jeu commencé! Le score actuel est' + currentScore); // Ici, le deuxième paramètre que nous passons à levelOne est la fonction de rappel, c'est-à-dire une fonction qui est passée en paramètre. levelOne (currentScore, function (levelOneReturnedValue) {console.log ('Niveau un atteint! Le nouveau score est' + levelOneReturnedValue);}); } démarrer jeu ();

Une fois à l'intérieur de la fonction démarrer jeu (), nous appelons la fonction premier niveau () avec des paramètres comme score actuel et notre rôle rappeler ().

Quand nous appelons premier niveau () dans le cadre de la fonction démarrer jeu (), de manière asynchrone, JavaScript exécute la fonction premier niveau () et le fil principal continue avec la partie restante de notre code.

Cela signifie que nous pouvons faire toutes sortes d'opérations comme obtenir des données à partir d'une API, faire des calculs mathématiques, etc., ce qui peut prendre beaucoup de temps et par conséquent, nous ne bloquerons pas notre thread principal pour cela. Une fois la fonction (levelOne ()) vous avez terminé vos opérations, vous pouvez exécuter la fonction rappeler que nous avons traversé précédemment.

C'est une fonctionnalité très utile de la programmation de fonctions, car les fonctions rappels ils nous permettent de gérer le code de manière asynchrone sans avoir à attendre une réponse. Par exemple, vous pouvez effectuer un appel ajax vers un serveur lent avec une fonction de rappeler et oubliez-le complètement et continuez avec le code restant. Une fois cet appel ajax résolu, la fonction de rappel s'exécute automatiquement.

Mais le Rappels ils peuvent devenir désagréables s'il y a plusieurs niveaux de rappels à exécuter dans une chaîne. Prenons l'exemple ci-dessus et ajoutons quelques niveaux supplémentaires à notre jeu.

function levelOne (valeur, rappel) {var newScore = valeur + 5; rappel (newScore); } function levelTwo (valeur, rappel) {var newScore = valeur + 10; rappel (newScore); } function levelThree (valeur, rappel) {var newScore = valeur + 30; rappel (newScore); } // Notez qu'il n'est pas nécessaire de faire référence à la fonction de rappel comme un rappel lors de l'appel de levelOne (), levelTwo () ou levelTree (), car elle peut être nommée n'importe quoi. function startGame () {var currentScore = 5; console.log ('Jeu commencé! Le score actuel est' + currentScore); levelOne (currentScore, function (levelOneReturnedValue) {console.log ('Niveau un atteint! Le nouveau score est' + levelOneReturnedValue); levelTwo (levelOneReturnedValue, function (levelTwoReturnedValue) {console.log (Niveau deux atteint! Le nouveau score est '+ levelTwalueReturn) ; levelThree (levelTwoReturnedValue, function (levelThreeReturnedValue) {console.log ('Niveau trois atteint! Le nouveau score est' + levelThreeReturnedValue);});});}); } démarrer jeu ();

Attendez, que vient de se passer? Nous avons ajouté deux nouvelles fonctions pour la logique de niveau, levelTwo () y levelThree (). Dans le rappel de levelOne (ligne #22), fonction d'appel levelTwo () avec une fonction de rappeler et le résultat de rappeler de premier niveau. Et la même chose se répète pour la fonction de niveau trois.

Imaginez maintenant ce que deviendra ce code si nous implémentions la même logique pour 10 autres niveaux. Êtes-vous déjà en train de paniquer? Eh bien, je fais! À mesure que le nombre de fonctions de rappel imbriquées augmente, le code devient plus difficile à lire et encore plus difficile à déboguer.

Ceci est souvent appelé affectueusement un rappel de l'enfer. Y a-t-il un moyen de sortir de cet enfer de rappel?

Je te promets qu'il y a un meilleur moyen

Javascript a commencé à prendre en charge Les promesses de l'ES6. Les promesses sont essentiellement des objets qui représentent l'achèvement (ou l'échec) d'une opération asynchrone et sa valeur résultante.

Essayons de réécrire notre exemple de rappel de l'enfer avec des promesses maintenant.

function levelOne (valeur) {var promise, newScore = valeur + 5; return promise = nouvelle promesse (fonction (résoudre) {résoudre (newScore);}); } function levelTwo (valeur) {var promise, newScore = value + 10; return promise = nouvelle promesse (fonction (résoudre) {résoudre (newScore);}); } function levelThree (valeur) {var promise, newScore = value + 30; return promise = nouvelle promesse (fonction (résoudre) {résoudre (newScore);}); } var startGame = new Promise (function (résoudre, rejeter) {var currentScore = 5; console.log ('Jeu commencé! Le score actuel est' + currentScore); résoudre (currentScore);}); // La réponse de startGame est automatiquement transmise à la fonction dans la fenêtre de dialogue suivante. startGame.then (levelOne) .then (function (result) {// la valeur du résultat est la promesse renvoyée par la fonction levelOne console.log ('Vous avez atteint le niveau un! Le nouveau score est' + résultat); return result;}) .then (levelTwo) .then (function (result) {console.log ('Vous avez atteint le niveau deux! Le nouveau score est' + result); return result;}) .then (levelThree) .then ( function (result) {console.log ('Vous avez atteint le niveau trois! Le nouveau score est' + résultat);});

Nous avons réécrit nos fonctions de niveau (un / deux / trois) pour supprimer les rappels du paramètre de fonction et au lieu d'appeler la fonction de rappel en leur sein, nous les avons remplacés par des promesses.

Une fois résolu démarrer jeu, nous pouvons simplement appeler une méthode .ensuite () dessus et gérer le résultat. Nous pouvons enchaîner plusieurs promesses les unes après les autres avec chaînage .ensuite () .

Cela rend tout le code beaucoup plus lisible et plus facile à comprendre en termes de ce qui se passe, puis de ce qui se passe ensuite et ainsi de suite.

La raison profonde pour laquelle les promesses sont souvent meilleures est qu'elles sont plus composables, ce qui signifie que la combinaison de plusieurs promesses "fonctionne juste", alors que la combinaison de plusieurs rappels ne fonctionne souvent pas.

Aussi, lorsque nous avons un seul rappel contre une seule promesse, il est vrai qu'il n'y a pas de différence significative. C'est lorsque vous avez un million de rappels contre un million de promesses que le code basé sur les promesses a tendance à être beaucoup mieux.

D'accord, nous avons réussi à échapper à l'enfer des rappels et à rendre notre code beaucoup plus lisible avec des promesses. Mais que se passerait-il si je vous disais qu'il existe un moyen de le rendre plus propre et plus lisible?

(a) Attendez pour ça

Async-wait est pris en charge en javascript depuis ECMA2017. Ils vous permettent d'écrire du code basé sur des promesses comme s'il s'agissait de code synchrone, mais sans bloquer le thread principal. Ils rendent votre code asynchrone moins «intelligent» et plus lisible.

Pour être honnête, les asyncrasies ne sont rien de plus que du sucre syntaxique en plus des promesses, mais elles donnent au code asynchrone l'apparence et le comportement un peu plus du code synchrone - c'est précisément là que réside leur pouvoir.

Si vous utilisez le mot clé Async avant de définir une fonction, vous pouvez utiliser l'option wait dans la fonction. Lorsque vous attendez une promesse, la fonction s'arrête d'une manière qui ne se bloque pas tant que la promesse n'est pas remplie. Si la promesse est remplie, la valeur est récupérée. Si la promesse est rejetée, la valeur rejetée est libérée.

Voyons maintenant à quoi ressemble notre logique de jeu une fois que nous l'avons réécrit avec async-attend.

function levelOne (valeur) {var promise, newScore = valeur + 5; return promise = nouvelle promesse (fonction (résoudre) {résoudre (newScore);}); } function levelTwo (valeur) {var promise, newScore = value + 10; return promise = nouvelle promesse (fonction (résoudre) {résoudre (newScore);}); } function levelThree (valeur) {var promise, newScore = value + 30; return promise = nouvelle promesse (fonction (résoudre) {résoudre (newScore);}); } // le mot clé async indique au moteur javascript que toute fonction de cette fonction qui a le mot clé await doit être traitée comme du code asynchrone et ne doit continuer à s'exécuter qu'après la résolution ou l'échec de cette fonction.
fonction asynchrone startGame () {var currentScore = 5; console.log ('Jeu commencé! Le score actuel est' + currentScore); currentScore = attendre levelOne (currentScore); console.log ('Vous avez atteint le niveau un! Le nouveau score est' + currentScore); currentScore = attendre levelTwo (currentScore); console.log ('Vous avez atteint le niveau deux! Le nouveau score est' + currentScore); currentScore = attendre levelThree (currentScore); console.log (Vous avez atteint le niveau trois! Le nouveau score est '+ currentScore); } démarrer jeu ();

Immédiatement, notre code devient beaucoup plus lisible, mais il y a plus à Async-wait.

La gestion des erreurs est l'une des principales fonctionnalités d'Async-await qui se démarque. Nous pouvons enfin gérer à la fois les erreurs synchrones et asynchrones avec la même construction avec try and catch, ce qui était pénible avec des promesses sans dupliquer les blocs try-catch.

La deuxième meilleure amélioration dans le monde des bonnes vieilles promesses est le débogage de code. Lorsque nous écrivons des promesses basées sur des fonctions fléchées, nous ne pouvons pas définir de points d'arrêt dans nos fonctions fléchées, le débogage est donc parfois difficile. Mais avec async-awaits, le débogage est comme un extrait de code synchrone

R Marketing Numérique