﻿1
00:00:01,300 --> 00:00:03,370
‫Instructeur : Prenons maintenant une minute pour en savoir plus

2
00:00:03,370 --> 00:00:06,370
‫sur la nature asynchrone de Node. js, qui

3
00:00:06,370 --> 00:00:09,510
‫inclut des sujets absolument fondamentaux,

4
00:00:09,510 --> 00:00:13,010
‫comme le code synchrone, asynchrone, bloquant

5
00:00:13,010 --> 00:00:15,140
‫et non bloquant.

6
00:00:15,140 --> 00:00:17,810
‫Et tout cela sera vraiment important pour

7
00:00:17,810 --> 00:00:21,090
‫comprendre tout ce qui se passe tout au long

8
00:00:21,090 --> 00:00:22,503
‫de cette section.

9
00:00:24,240 --> 00:00:27,620
‫Donc, ce morceau de code que nous avons écrit

10
00:00:27,620 --> 00:00:31,830
‫dans la dernière leçon, pour lire un fichier puis enregistrer son contenu

11
00:00:31,830 --> 00:00:34,400
‫dans une variable, était d'une manière dite

12
00:00:34,400 --> 00:00:36,840
‫synchrone, ce qui signifie simplement

13
00:00:36,840 --> 00:00:41,330
‫que chaque instruction est essentiellement traitée l'une après l'autre, ligne par ligne.

14
00:00:41,330 --> 00:00:42,540
‫Dans cet exemple,

15
00:00:42,540 --> 00:00:45,630
‫tout d'abord, le module du système de fichiers est

16
00:00:45,630 --> 00:00:47,630
‫requis, puis le fichier est

17
00:00:47,630 --> 00:00:50,900
‫lu, puis nous enregistrons le résultat dans la console.

18
00:00:50,900 --> 00:00:53,340
‫Vous voyez donc que chaque ligne

19
00:00:53,340 --> 00:00:57,340
‫de code attend essentiellement le résultat de la ligne précédente.

20
00:00:57,340 --> 00:00:59,440
‫Maintenant, cela peut devenir un

21
00:00:59,440 --> 00:01:01,500
‫problème, surtout avec des opérations

22
00:01:01,500 --> 00:01:04,190
‫lentes, car chaque ligne bloque l'exécution du

23
00:01:04,190 --> 00:01:05,710
‫reste du code.

24
00:01:05,710 --> 00:01:08,120
‫Et donc, on dit que

25
00:01:08,120 --> 00:01:12,290
‫le code synchrone est aussi appelé code bloquant car, encore une

26
00:01:12,290 --> 00:01:15,080
‫fois, une certaine opération ne peut être

27
00:01:15,080 --> 00:01:17,740
‫exécutée qu'une fois la précédente terminée.

28
00:01:17,740 --> 00:01:20,850
‫Et à cause de la façon dont Node. js a été

29
00:01:20,850 --> 00:01:24,220
‫conçu, cela devient un énorme problème, comme nous le verrons

30
00:01:24,220 --> 00:01:26,190
‫en détail dans la diapositive suivante.

31
00:01:26,190 --> 00:01:28,500
‫La solution à ce problème dans

32
00:01:28,500 --> 00:01:32,160
‫Node consiste donc à utiliser du code asynchrone non bloquant.

33
00:01:32,160 --> 00:01:35,380
‫Ainsi, dans le code asynchrone, nous téléchargeons un

34
00:01:35,380 --> 00:01:38,470
‫travail lourd à traiter essentiellement en arrière-plan.

35
00:01:38,470 --> 00:01:40,820
‫Et puis, une fois ce travail

36
00:01:40,820 --> 00:01:43,370
‫terminé, une fonction de rappel que nous enregistrons

37
00:01:43,370 --> 00:01:45,730
‫auparavant est appelée pour gérer le résultat.

38
00:01:45,730 --> 00:01:47,540
‫Et pendant tout ce

39
00:01:47,540 --> 00:01:50,380
‫temps, le reste du code peut toujours

40
00:01:50,380 --> 00:01:52,910
‫s'exécuter sans être bloqué par la

41
00:01:52,910 --> 00:01:55,820
‫lourde tâche, qui s'exécute désormais en arrière-plan.

42
00:01:55,820 --> 00:01:59,520
‫Donc, cela signifie que nous pouvons effectivement différer ou

43
00:01:59,520 --> 00:02:01,620
‫réagir dans le futur

44
00:02:01,620 --> 00:02:04,530
‫afin de rendre le code non

45
00:02:04,530 --> 00:02:07,676
‫bloquant et c'est, bien sûr, bien meilleur.

46
00:02:07,676 --> 00:02:09,287
‫Logique?

47
00:02:09,287 --> 00:02:12,203
‫Ainsi, dans cet exemple, nous utilisons

48
00:02:12,203 --> 00:02:16,390
‫la fonction asynchrone readFile, qui accepte une fonction de rappel.

49
00:02:16,390 --> 00:02:19,120
‫Cela commencera à lire le fichier

50
00:02:19,120 --> 00:02:22,360
‫en arrière-plan, puis, passera immédiatement à l'instruction suivante, en

51
00:02:22,360 --> 00:02:25,830
‫imprimant sur la console le fichier de lecture de chaîne.

52
00:02:25,830 --> 00:02:30,530
‫Donc, encore une fois, voyez-vous, nous ne bloquons pas l'exécution ici.

53
00:02:30,530 --> 00:02:33,860
‫Ensuite, lorsque le fichier est enfin complètement lu, la fonction

54
00:02:33,860 --> 00:02:35,870
‫de rappel sera appelée, et

55
00:02:35,870 --> 00:02:38,100
‫ainsi, les données qui ont été lues

56
00:02:38,100 --> 00:02:40,270
‫seront alors imprimées sur la console.

57
00:02:40,270 --> 00:02:41,890
‫C'est donc assez différent

58
00:02:41,890 --> 00:02:43,893
‫de la version synchrone, n'est-ce pas ?

59
00:02:44,870 --> 00:02:46,710
‫Maintenant, la question ici est,

60
00:02:46,710 --> 00:02:49,490
‫pourquoi est-ce qu'il doit en être ainsi ?

61
00:02:49,490 --> 00:02:53,940
‫Quel est le problème avec le blocage de l'exécution du code dans Node. js ?

62
00:02:53,940 --> 00:02:57,030
‫Ou, en d'autres termes, pourquoi utilisons-nous si souvent le

63
00:02:57,030 --> 00:02:59,770
‫rappel dans Node. js ?

64
00:02:59,770 --> 00:03:01,523
‫Eh bien, découvrons.

65
00:03:03,110 --> 00:03:05,930
‫Et pour comprendre ces questions, la première chose

66
00:03:05,930 --> 00:03:08,220
‫que nous devons comprendre est le

67
00:03:08,220 --> 00:03:11,260
‫fait qu'un Node. js, qui est

68
00:03:11,260 --> 00:03:13,760
‫l'endroit où notre application s'exécute,

69
00:03:13,760 --> 00:03:16,410
‫il n'y a qu'un seul thread.

70
00:03:16,410 --> 00:03:19,720
‫Et le fil est comme un ensemble d'instructions exécutées

71
00:03:19,720 --> 00:03:22,200
‫dans le processeur de l'ordinateur.

72
00:03:22,200 --> 00:03:25,200
‫Donc, fondamentalement, le thread est l'endroit où

73
00:03:25,200 --> 00:03:29,270
‫notre code est réellement exécuté dans le processeur d'une machine.

74
00:03:29,270 --> 00:03:33,120
‫Alors, rappelez-vous, Node. js est essentiellement monothread

75
00:03:33,120 --> 00:03:36,980
‫et donc, pour chaque application, il n'y a qu'un seul thread.

76
00:03:36,980 --> 00:03:40,300
‫C'est juste la façon dont Node. js a été conçu.

77
00:03:40,300 --> 00:03:43,050
‫Maintenant, cela signifie que tous les

78
00:03:43,050 --> 00:03:46,960
‫utilisateurs qui accèdent à votre application utilisent tous le même

79
00:03:46,960 --> 00:03:50,040
‫thread, donc, fondamentalement, accèdent au même thread.

80
00:03:50,040 --> 00:03:53,410
‫Ainsi, chaque fois qu'ils interagissent avec l'application,

81
00:03:53,410 --> 00:03:55,860
‫le code exécuté pour

82
00:03:55,860 --> 00:03:59,810
‫chaque utilisateur sera exécuté dans le même thread au

83
00:03:59,810 --> 00:04:02,490
‫même endroit sur l'ordinateur exécutant l'application.

84
00:04:02,490 --> 00:04:04,900
‫Et cela est vrai, peu importe

85
00:04:04,900 --> 00:04:09,900
‫si vous avez cinq utilisateurs, comme dans ce diagramme, ou 5 000 ou 5 millions.

86
00:04:10,610 --> 00:04:12,080
‫Très bien?

87
00:04:12,080 --> 00:04:15,310
‫Maintenant, cela signifie également que lorsqu'un utilisateur verrouille le

88
00:04:15,310 --> 00:04:17,960
‫thread unique avec du code synchrone, comme

89
00:04:17,960 --> 00:04:19,640
‫nous venons de

90
00:04:19,640 --> 00:04:22,280
‫le voir, tous les autres utilisateurs devront

91
00:04:22,280 --> 00:04:24,680
‫attendre la fin de cette exécution.

92
00:04:24,680 --> 00:04:27,010
‫Et ce n'est peut-être pas un gros

93
00:04:27,010 --> 00:04:29,800
‫problème si vous avez environ cinq utilisateurs, mais

94
00:04:29,800 --> 00:04:33,350
‫ce sera certainement le cas pour des milliers, voire des

95
00:04:33,350 --> 00:04:35,393
‫millions d'utilisateurs en même temps.

96
00:04:36,440 --> 00:04:39,830
‫Donc, imaginez qu'un utilisateur accède à votre application et

97
00:04:39,830 --> 00:04:43,280
‫qu'il y ait un énorme fichier synchrone lu dans votre

98
00:04:43,280 --> 00:04:46,630
‫code qui prendra environ une seconde à charger.

99
00:04:46,630 --> 00:04:49,920
‫Cela signifiera, bien sûr, que pendant cette

100
00:04:49,920 --> 00:04:52,370
‫seconde, tous les autres

101
00:04:52,370 --> 00:04:57,370
‫utilisateurs devront attendre car toute l'exécution est bloquée pendant cette seconde.

102
00:04:57,490 --> 00:05:00,680
‫Ainsi, si ces autres utilisateurs souhaitent effectuer des tâches

103
00:05:00,680 --> 00:05:02,940
‫simples, comme se connecter à votre

104
00:05:02,940 --> 00:05:06,900
‫application ou simplement demander des données, ils ne pourront pas le faire.

105
00:05:06,900 --> 00:05:11,150
‫Ils devront attendre la fin de la lecture du fichier.

106
00:05:11,150 --> 00:05:15,130
‫Ce n'est que lorsque cela se produira qu'ils pourront enfin effectuer

107
00:05:15,130 --> 00:05:18,113
‫les tâches les plus simples, l'une après l'autre.

108
00:05:19,260 --> 00:05:23,290
‫Maintenant, veuillez noter qu'il s'agit d'une version très simplifiée de ce qui se passe

109
00:05:23,290 --> 00:05:27,010
‫réellement dans les coulisses de Node. js, c'est

110
00:05:27,010 --> 00:05:29,880
‫pourquoi nous reviendrons sur tout

111
00:05:29,880 --> 00:05:33,760
‫cela dans la section suivante pour mieux

112
00:05:33,760 --> 00:05:38,090
‫comprendre comment Node. js gère le code asynchrone sous le capot.

113
00:05:38,090 --> 00:05:39,370
‫Mais à ce

114
00:05:39,370 --> 00:05:42,170
‫stade, cela vous suffit pour comprendre le concept.

115
00:05:42,170 --> 00:05:44,560
‫Il vaut mieux y aller étape par

116
00:05:44,560 --> 00:05:46,520
‫étape et ne pas le

117
00:05:46,520 --> 00:05:49,220
‫rendre trop confus dès le début, d'accord ?

118
00:05:49,220 --> 00:05:51,660
‫Quoi qu'il en soit, c'est ainsi

119
00:05:51,660 --> 00:05:54,620
‫que la situation se déroulerait avec du code de

120
00:05:54,620 --> 00:05:58,460
‫blocage synchrone, ce qui est évidemment une expérience terrible pour vos utilisateurs.

121
00:05:58,460 --> 00:06:01,180
‫Et donc, c'est vraiment votre travail en tant que

122
00:06:01,180 --> 00:06:03,260
‫développeur d'éviter ce genre de situations

123
00:06:03,260 --> 00:06:05,113
‫en utilisant du code asynchrone.

124
00:06:07,150 --> 00:06:10,180
‫Donc, pour la même situation, nous devrions, bien sûr, utiliser

125
00:06:10,180 --> 00:06:12,780
‫la fonction de lecture de fichier asynchrone, qui

126
00:06:12,780 --> 00:06:15,190
‫au lieu de bloquer le seul

127
00:06:15,190 --> 00:06:17,700
‫thread, fait le gros du travail en arrière-plan,

128
00:06:17,700 --> 00:06:20,170
‫où elle reste essentiellement jusqu'à ce qu'elle

129
00:06:20,170 --> 00:06:22,700
‫ait fini de lire les données du fichier.

130
00:06:22,700 --> 00:06:25,950
‫Bien entendu, nous enregistrons ensuite également une fonction

131
00:06:25,950 --> 00:06:29,490
‫de rappel à appeler une fois les données disponibles.

132
00:06:29,490 --> 00:06:32,130
‫Et dans ce scénario, tous les autres

133
00:06:32,130 --> 00:06:35,100
‫utilisateurs peuvent alors effectuer leurs tâches dans un

134
00:06:35,100 --> 00:06:38,710
‫seul thread, l'un après l'autre, pendant que le fichier est

135
00:06:38,710 --> 00:06:40,390
‫toujours lu en arrière-plan.

136
00:06:40,390 --> 00:06:43,870
‫Maintenant, une fois les données lues, notre fonction de

137
00:06:43,870 --> 00:06:46,240
‫rappel sera, bien sûr, appelée pour

138
00:06:46,240 --> 00:06:51,240
‫être exécutée dans le thread unique principal afin de traiter les données lues.

139
00:06:51,380 --> 00:06:52,460
‫Et c'est tout.

140
00:06:52,460 --> 00:06:54,720
‫C'est un aperçu de la façon dont Node. js gère

141
00:06:54,720 --> 00:06:58,000
‫le comportement asynchrone afin d'implémenter le modèle d'E/S

142
00:06:58,000 --> 00:07:00,850
‫non bloquant dont nous avons parlé

143
00:07:00,850 --> 00:07:03,670
‫dans la conférence d'introduction, d'accord ?

144
00:07:03,670 --> 00:07:07,240
‫Et I/O signifie simplement entrée-sortie, ce qui revient

145
00:07:07,240 --> 00:07:10,810
‫essentiellement à accéder au système de fichiers et

146
00:07:10,810 --> 00:07:13,500
‫à gérer les requêtes réseau.

147
00:07:13,500 --> 00:07:16,470
‫C'est en fait toute la raison pour laquelle Node. js est entièrement

148
00:07:16,470 --> 00:07:18,830
‫conçu autour des rappels, comme vous le

149
00:07:18,830 --> 00:07:21,190
‫verrez tout au long du cours.

150
00:07:21,190 --> 00:07:24,090
‫Dans d'autres langages de programmation, comme PHP, cela

151
00:07:24,090 --> 00:07:27,260
‫fonctionne très différemment car vous obtenez, en gros, un

152
00:07:27,260 --> 00:07:29,640
‫nouveau thread pour chaque nouvel utilisateur,

153
00:07:29,640 --> 00:07:32,020
‫ce qui est un paradigme

154
00:07:32,020 --> 00:07:34,600
‫complètement différent et fonctionne vraiment complètement différemment.

155
00:07:34,600 --> 00:07:37,620
‫Mais le créateur de Node. js a trouvé

156
00:07:37,620 --> 00:07:40,660
‫que ce modèle était la meilleure solution pour créer

157
00:07:40,660 --> 00:07:42,980
‫des applications Web hautement performantes et évolutives.

158
00:07:42,980 --> 00:07:46,810
‫Maintenant, juste pour terminer ici, il est important de savoir

159
00:07:46,810 --> 00:07:48,830
‫que, lorsque nous utilisons des

160
00:07:48,830 --> 00:07:53,380
‫rappels dans notre code, cela ne le rend pas automatiquement asynchrone, d'accord ?

161
00:07:53,380 --> 00:07:56,520
‫Donc, passer des fonctions à d'autres fonctions est

162
00:07:56,520 --> 00:07:58,780
‫assez courant en JavaScript,

163
00:07:58,780 --> 00:08:01,830
‫mais bien sûr, encore une fois, cela

164
00:08:01,830 --> 00:08:05,110
‫ne les rend pas automatiquement asynchrones, d'accord ?

165
00:08:05,110 --> 00:08:09,150
‫Cela ne fonctionne que de cette façon pour certaines fonctions de l'API Node,

166
00:08:09,150 --> 00:08:11,210
‫telles que la fonction readFile

167
00:08:11,210 --> 00:08:14,823
‫et bien d'autres, à mesure que les gens l'exploreront à l'avenir.

168
00:08:16,610 --> 00:08:18,500
‫Et maintenant, juste pour

169
00:08:18,500 --> 00:08:21,200
‫finir, puisque nous parlons ici de code asynchrone,

170
00:08:21,200 --> 00:08:24,630
‫juste une dernière remarque sur les fonctions de rappel.

171
00:08:24,630 --> 00:08:27,670
‫Ainsi, ce modèle de rappel dont nous venons de

172
00:08:27,670 --> 00:08:29,370
‫parler, où une fonction

173
00:08:29,370 --> 00:08:32,300
‫est appelée une fois que la précédente a

174
00:08:32,300 --> 00:08:36,970
‫terminé son travail, peut rapidement conduire à un code difficile à lire et ingérable.

175
00:08:36,970 --> 00:08:39,830
‫Prenons simplement cet exemple où le deuxième fichier

176
00:08:39,830 --> 00:08:41,870
‫lu dépend du premier,

177
00:08:41,870 --> 00:08:44,800
‫ensuite, le troisième fichier lu dépend du second,

178
00:08:44,800 --> 00:08:47,560
‫et enfin, nous voulons utiliser les données finales

179
00:08:47,560 --> 00:08:49,700
‫pour écrire un fichier en conséquence.

180
00:08:49,700 --> 00:08:52,690
‫Cela semble assez déroutant, non?

181
00:08:52,690 --> 00:08:54,950
‫Je veux dire, ça va très

182
00:08:54,950 --> 00:08:57,330
‫bien fonctionner, mais c'est juste difficile à

183
00:08:57,330 --> 00:09:00,110
‫raisonner et c'est juste avec quatre niveaux de profondeur.

184
00:09:00,110 --> 00:09:02,980
‫Imaginez que vous ayez 10 ou 20 niveaux,

185
00:09:02,980 --> 00:09:05,850
‫ce qui n'est en fait pas si rare.

186
00:09:05,850 --> 00:09:09,440
‫Quoi qu'il en soit, c'est ce que nous appelons l'enfer du rappel.

187
00:09:09,440 --> 00:09:11,370
‫C'est un problème tellement

188
00:09:11,370 --> 00:09:13,780
‫courant qu'il a déjà son propre nom.

189
00:09:13,780 --> 00:09:16,920
‫Et remarquez-vous cette forme triangulaire ici ?

190
00:09:16,920 --> 00:09:20,840
‫C'est un signe très clair que vous êtes dans un enfer de rappel.

191
00:09:20,840 --> 00:09:24,350
‫Maintenant, comment échapper à l'enfer des rappels ?

192
00:09:24,350 --> 00:09:27,600
‫Eh bien, nous pouvons utiliser des outils plus

193
00:09:27,600 --> 00:09:30,730
‫avancés pour gérer le code asynchrone,

194
00:09:30,730 --> 00:09:34,150
‫comme les promesses ES6 ou encore mieux, ES8 async/await.

195
00:09:34,150 --> 00:09:36,320
‫Maintenant, le modèle dont nous venons de

196
00:09:36,320 --> 00:09:37,890
‫parler sera toujours le même.

197
00:09:37,890 --> 00:09:39,960
‫Nous avons juste des manières

198
00:09:39,960 --> 00:09:43,370
‫plus élégantes de traiter le code lui-même et de l'écrire.

199
00:09:43,370 --> 00:09:45,830
‫Et il y a toute une section

200
00:09:45,830 --> 00:09:50,090
‫facultative plus tard dans le cours sur les promesses et aussi, async/wait, donc

201
00:09:50,090 --> 00:09:52,590
‫au cas où vous ne les connaissez pas.

202
00:09:52,590 --> 00:09:55,140
‫Mais pour l'instant, nous continuerons à utiliser les rappels

203
00:09:55,140 --> 00:09:57,900
‫car c'est ce que Node utilisait à l'origine et

204
00:09:57,900 --> 00:10:00,100
‫autour duquel il a été conçu.

205
00:10:00,100 --> 00:10:02,030
‫Et maintenant, cela étant

206
00:10:02,030 --> 00:10:05,240
‫dit, passons à autre chose et utilisons ce modèle asynchrone

207
00:10:05,240 --> 00:10:07,233
‫en pratique pour la première fois.

