Avertissement
N'installez pas ce package en tant que dépendance! (Voir: commencer)
Actuellement, les promesses sont le moyen de facto de gérer les tâches asynchrones en JavaScript, et à cause de cela, ils sont une partie fondamentale des connaissances de tout développeur JavaScript.
Cependant, lorsque nous apprenons les promesses pour la première fois, nous n'apprenons que suffisamment pour nous en sortir , c'est-à-dire que nous apprenons un peu comment utiliser les promesses (de nos jours, très probablement avec async/await uniquement), la Promise.all méthode et c'est tout.
Bien que cette approche ait du sens pour les débutants car il suffit de résoudre la plupart des problèmes dans leur vie quotidienne, un problème récurrent est qu'ils s'arrêtent là , c'est-à-dire qu'ils ne dépassent jamais ces connaissances initiales.
Et c'est précisément cette posture "apprenez juste assez pour obtenir" qui maintient de nombreux développeurs à leur niveau actuel, car la résolution de problèmes plus complexes nécessite une compréhension plus profonde.
Donc, si vous voulez faire passer vos compétences en développeur au niveau supérieur , nager dans des eaux peu profondes ne le coupera pas , vous devez aller plus loin , vous devez comprendre pleinement les promesses, et comment ils fonctionnent, vous devez être compétent dans async/await , then/catch les styles de promesses de promesse et de gérer la manière la plus efficace.
De plus, comme les promesses sont finalement une abstraction pour gérer les tâches asynchrones, être en mesure de résoudre les problèmes courants liés à la programmation asynchrone est un must.
Dans cet esprit, nous avons créé ce projet précisément pour vous aider à faire cette plongée profonde dans les promesses et la programmation asynchrone.
En fournissant à la fois des explications et des exercices pratiques entourant ces sujets, ce projet vise à être votre compagnon dans ce voyage pour les maîtriser.
Même si vous êtes déjà un développeur chevronné, vous pourriez apprendre une chose ou deux, comme, par exemple, vous voudrez peut-être essayer de résoudre concrete/parallelMaxConcurrency , concrete/concurrencyOverride , concrete/extractingResolvers et /foundation/promise car ils présentent des défis intéressants.
Important
Ce projet n'est pas destiné aux personnes qui apprennent les promesses pour la première fois, car elle suppose que vous avez au moins quelques connaissances de base des promesses, ce qu'ils représentent et comment les utiliser à la fois avec async/await then/catch .
Avertissement
ATTENTION: Ce dépôt n'est pas censé être cloné sauf si vous contribuez si vous êtes un utilisateur final, veuillez suivre les instructions ci-dessous
Tout d'abord, pour installer le projet, exécutez:
npm create promises-training@latestNote
Ce projet est axé sur l'exercice, donc l'objectif principal est de les résoudre.
Parfois, il y aura des explications avec les exercices pour vous aider à comprendre ce qui doit être fait, ainsi que un contexte de résolution du problème.
Les exercices sont divisés en trois catégories:
Important
Il n'y a pas d'ordre spécifique pour les catégories, vous pouvez commencer par l'un d'eux et passer à un autre avant même de terminer complètement l'autre. Cependant, les exercices ont des niveaux différents qui seront discutés ensuite.
Les exercices sont situés dans les dossiers src/exercises/<category> , où <category> est l'une des catégories mentionnées ci-dessus.
Pour les exercices de graphique , les explications de base sont situées dans ce ReadMe, dans la section Graphique, et pour chaque exercice, il y a un graph.png qui décrit le graphique de dépendance pour cet exercice spécifique.
Pour les exercices de béton et de fondation , les explications sont situées dans le README.md à l'intérieur du dossier de l'exercice (par exemple src/exercises/concrete/parallelChunks/README.md ).
Pour résoudre un exercice, vous devez modifier le fichier src/exercises/<category>/<exercise>/exercise.ts .
Après avoir résolu un exercice, vous pouvez vérifier votre solution en fonctionnant:
npm run check < category > / < exercise > Les tests sont situés dans src/tests .
Généralement, vous ne travaillerez qu'à l'intérieur du dossier Exercices car les tests sont conçus d'une manière qu'ils vous disent exactement ce qui s'est passé sans avoir à regarder leur mise en œuvre, mais si pour une raison quelconque, vous êtes coincé ou curieux, vous pouvez les jeter un œil.
Le dossier src/lib est destiné à un usage interne uniquement, alors ne vous inquiétez pas.
De plus, pour maintenir votre installation à l'avenir compatible avec les versions futures, ne modifiez aucun fichier en dehors du dossier src/exercises .
Outre les catégories, les exercices sont également divisés en niveaux, où les exercices augmentent en difficulté à mesure que vous progressez à travers les niveaux.
Il y a trois niveaux:
Gardez à l'esprit que cette classification est quelque peu subjective, donc YMMV et vous n'avez pas nécessairement besoin de terminer tous les exercices à un niveau pour passer à la suivante.
Note
Comme vous pouvez le voir, actuellement, il n'y a pas beaucoup d'exercices avancés, mais l'idée est que de nouveaux exercices seront ajoutés au fil du temps.
Chaque exercice est accompagné de tests automatisés afin que vous puissiez vérifier votre solution.
Pour exécuter un seul exercice, exécuter:
npm run check < category > / < exercise > Par exemple, pour exécuter les tests pour l'exercice parallelChunks , exécutez: exécuter:
npm run check concrete/parallelChunksOu, pour exécuter le graphique Exercice numéro 2, exécutez:
npm run check graph/2/test.test.tsNote
Dans l'exemple précédent, nous devions annexer /test.test.ts au fichier de l'exercice, sinon il fonctionnerait également pour d'autres exercices de graphe à commencer par 2 , par exemple: exercices de 2 à 29.
Nous utilisons Viest comme Runner de test, donc toutes ses options CLI sont disponibles.
En outre, il est important de mentionner que les exercices de graphiques ont des particularités, dans le sens où ils sont générés automatiquement à partir du graphique lui-même , et à cause de cela, certains exercices ont un grand nombre de tests (certains exercices ont plus de 100 000 tests).
Bien sûr, nous ne les exécutons pas tous car il serait prohibitif lent, nous ne les exécutons donc qu'un sous-ensemble et il est possible de modifier le nombre de tests exécutés et le sous-ensemble .
Vous pouvez en savoir plus dans la section des exercices de graphique.
Actuellement, il existe trois catégories d'exercices:
Une grande partie du traitement des tâches asynchrones est de les orchestrer afin que chaque tâche commence dès que possible, et pour orchestrer correctement ces tâches, nous devons comprendre les relations de dépendance entre eux.
Dans cette catégorie, vous serez présenté avec un graphique de dépendance dans chaque exercice, puis vous orchestrez les tâches du graphique de la manière la plus efficace possible.
Étant donné que l'exercice est axé sur l'orchestration elle-même, les tâches sont créées en appelant createPromise(label) , où label est une chaîne qui identifie la tâche.
Prenez ce graphique, par exemple:

Il y a deux tâches dans ce graphique, A et B , et B dépend de A , qui est représenté par la flèche qui sort de B et pointe vers A .
Cela signifie que B ne peut démarrer qu'après avoir terminé A et A , car il ne dépend pas d'une autre tâche, peut commencer tout de suite.
Ainsi, l'implémentation la plus efficace pour ce graphique serait:
await createPromise ( "A" ) ;
await createPromise ( "B" ) ;Les tâches peuvent également dépendre de plus d'une tâche:

Dans ce graphique, C dépend à la fois de A et B , de sorte qu'il ne peut démarrer qu'après la fin A et B
Cependant, A et B ne dépendent pas d'une autre tâche, ils peuvent donc commencer tout de suite.
L'implémentation la plus efficace pour ce graphique serait:
await Promise . all ( [ createPromise ( "A" ) , createPromise ( "B" ) ] ) ;
await createPromise ( "C" ) ;Les tâches peuvent également avoir plusieurs ensembles de dépendances différents où, si l'un des ensembles est satisfait, alors la tâche peut démarrer:

Dans ce graphique, C dépend de A ou de B , qui est représenté en utilisant différentes couleurs pour chaque ensemble de dépendances. Les couleurs elles-mêmes n'ont pas de sens spécifique, elles sont utilisées comme celle-ci juste pour que les dépendances se distinguent les unes des autres.
Par conséquent, C peut commencer dès que A ou B a terminé.
await Promise . any ( [ createPromise ( "A" ) , createPromise ( "B" ) ] ) ;
await createPromise ( "C" ) ;Enfin et surtout, les promesses ont deux résultats possibles: ils peuvent être remplis ou rejetés.

Dans ce graphique, nous avons la tâche B qui dépend d' A accomplissement et d'une tâche C qui dépend d' A .
Important
Les bords en pointillés sont utilisés pour promettre des refus.
Cela signifie que B ne peut démarrer qu'après que A a été rempli et que C ne peut démarrer qu'après le rejeté d' A
Comme un seul de ces résultats est possible, B ou C sera effectué.
Implémentation correspondante:
try {
await createPromise ( "A" ) ;
try {
await createPromise ( "B" ) ;
} catch { }
} catch {
await createPromise ( "C" ) ;
} Lorsque vous faites des exercices de graphique, vous remarquerez que trois fonctions sont exportées: mixed , asyncAwait , thenCatch .
L'idée est pour vous de fournir 3 implémentations différentes:
mixed : celui-ci est entièrement gratuit, vous pouvez mélanger à la fois Async / Await puis / Catch,asyncAwait : Dans celui-ci, vous ne devriez utiliser qu'async / attendrethenCatch : Dans celui-ci, vous ne devez utiliser que / catch.De cette façon, vous serez compétent dans les deux styles de manipulation de promesses.
De plus, à la fin du fichier, vous remarquerez que les exportations sont enveloppées dans un skipExercise , qui saute des tests pour cette implémentation spécifique afin qu'il ne jonche la sortie.
Lorsque vous implémentez une solution pour chacun de ces trois, supprimez l'appel skipExercise pour l'implémentation que vous souhaitez que les tests s'exécutent. Par exemple: si vous avez déjà implémenté la solution mixed , supprimez-en le skipExercise mais gardez celles pour asyncAwait et thenCatch jusqu'à ce que vous les implémentez.
Pour vous aider à déboguer votre implémentation pour les exercices du graphique, nous avons créé une interface utilisateur qui vous permet de simuler différents "chemins" d'exécution.
Pour ouvrir l'interface utilisateur, courez:
npm run graph:uiL'interface utilisateur est servie d'application Web et cela ressemble à ceci.

Explorons maintenant chaque section:

La barre latérale de gauche vous permet de sélectionner l'exercice que vous souhaitez déboguer.

Cette section supérieure vous permet de sélectionner l'implémentation que vous souhaitez déboguer.

La barre latérale droite vous permet de contrôler le flux d'exécution de l'exercice en résolvant / rejetant les promesses.
Au fur et à mesure que les promesses sont créées, de nouvelles entrées sont ajoutées à la barre latérale.

Cette section au centre montre les enregistrements des promesses qui ont été créées et résolues / rejetées à chaque étape.

Cette section en bas montre un résumé des promesses qui ont été résolues / rejetées à chaque étape, dans l'ordre.
Comme les exercices de graphiques sont basés sur les graphiques (duh), il est possible de générer automatiquement tous les tests possibles pour un exercice donné, ce que nous faisons.
Comme on pourrait l'imaginer, le nombre de tests générés est parfois énorme, nous avons donc un plafond sur le nombre maximum de tests exécutés.
De plus, pour éviter les biais, nous n'effectuons pas de tests dans l'ordre où ils ont été générés, nous les mélangeons à la place.
Ce mélange se produit juste après que les tests sont générés pour la première fois, de sorte que les tests sont déterministes , c'est-à-dire chaque fois que vous exécutez des tests de graphe, vous exécuterez le même sous-ensemble de tests.
Cependant, il est possible de modifier à la fois le capuchon et le sous-ensemble de tests exécutés.
Pour ajuster le capuchon, vous pouvez exécuter npm run graph:setGraphTestsCap <number> .
Par exemple, pour définir le plafond sur 10000, exécuter:
npm run graph:setGraphTestsCap 10000 Pour modifier le sous-ensemble de tests exécutés, vous pouvez exécuter npm run graph:shuffleGraphTestData <graph-exercise-number> , qui remaniera les tests de l'exercice de graphique spécifié, ce qui entraînera ensuite un sous-ensemble de tests différents.
Par exemple, pour remanier les tests pour l'exercice du graphique numéro 2, exécutez:
npm run graph:shuffleGraphTestData 2Les exercices de graphiques sont idéaux pour comprendre les relations de dépendance entre les tâches, cependant, ils ne couvrent pas le spectre complet des scénarios possibles, car seules les tâches dont les dépendances sont connues au moment de la compilation et fixes peuvent être représentées par un graphique.
Par conséquent, nous avons cette catégorie d'exercices concrets, où vous serez présenté avec des scénarios concrets que vous devrez mettre en œuvre.
Comme chaque exercice de cette catégorie est unique, leur description est colocalisée avec leur dossier.
Les exercices de fondation sont conçus pour vous aider à renforcer votre compréhension des fondements des promesses, en réimplémentant les fonctions liées aux promesses et, finalement, la promesse elle-même.
Les descriptions sont coloquées avec des exercices.
Des solutions aux exercices peuvent être trouvées dans ce dépôt, par exemple https://github.com/henriqueinonhe/promises-training/blob/master/src/execcises/concrete/concurrencyabort/exercise.ts.
Cependant, nous vous recommandons de vérifier les solutions uniquement après avoir résolu l'exercice vous-même, car l'objectif est que vous apprenions en résolvant les exercices.
Gardez également à l'esprit qu'actuellement, les solutions présentées ne sont pas nécessairement les meilleures , ce qui signifie que même si vos solutions ne ressemblent pas du tout à celles que vous trouverez ici, cela ne signifie pas qu'ils sont mauvais.
Pour faciliter la mise à niveau vers des versions plus récentes, nous avons créé un script de migration qui migre automatiquement votre installation vers la dernière version tout en préservant vos solutions.
Pour exécuter le script de migration, exécutez:
npm create promises-training@latest -- --migrateCe projet est sous licence sous CC-BY-NC-ND 4.0.
L'objectif derrière ce projet est d'être une ressource d'apprentissage gratuite et de rester libre et accessible pour toujours.
Voici une Q&R de quelques questions courantes concernant la licence:
Puis-je utiliser ce projet pour une étude de soi ou de groupe?
Oui, s'il vous plaît.
Puis-je utiliser ce projet dans une formation interne d'entreprise?
Oui, tant que vous créez le projet et indiquez clairement que le projet est librement accessible indépendamment de la formation.
Puis-je utiliser ce projet pour mes séances de mentorat / atelier rémunérées?
Oui, tant que vous crédisez le projet, indiquez clairement que le projet est librement accessible indépendamment du mentorat / de l'atelier, indiquez clairement que vous facturez votre temps et non pour le projet lui-même, indiquez clairement que le projet ne fait pas partie de votre propre matériel et indiquez clairement que nous ne vous appruons pas ou vos services.
Puis-je utiliser ce projet pour mon cours en ligne payé?
Oui, tant que vous crédisez le projet, indiquez clairement que le projet est librement accessible indépendamment du cours en ligne, indiquez clairement que vous facturez votre temps et non pour le projet lui-même, indiquez clairement que le projet ne fait pas partie de votre propre matériel et indiquez clairement que nous ne vous appuyons pas, vous ou vos services.
Puis-je créer une fourche de ce projet et l'utiliser à mes propres fins?
Non, vous ne pouvez pas. Vous ne pouvez utiliser ce projet qu'en tant que modification. Ceci est nécessaire pour empêcher les gens de créer des fourches, puis de les facturer.
Puis-je créer un cours en ligne basé sur ce projet?
Non, vous ne pouvez pas, parce que nous ne voulons pas que les gens créent des "emballages" autour de ce projet, puis les facturent.
Si vous avez des questions concernant la licence ou que vous souhaitez parler d'un cas d'utilisation spécifique, n'hésitez pas à me joindre à [email protected].