﻿1
00:00:01,300 --> 00:00:03,370
‫Istruttore: Prendiamoci ora un minuto per conoscere

2
00:00:03,370 --> 00:00:06,370
‫la natura asincrona di Node. js,

3
00:00:06,370 --> 00:00:09,510
‫che include argomenti assolutamente fondamentali,

4
00:00:09,510 --> 00:00:13,010
‫come codice sincrono, asincrono, bloccante

5
00:00:13,010 --> 00:00:15,140
‫e non bloccante.

6
00:00:15,140 --> 00:00:17,810
‫E tutto questo sarà davvero importante

7
00:00:17,810 --> 00:00:21,090
‫per capire tutto ciò che sta arrivando in

8
00:00:21,090 --> 00:00:22,503
‫questa sezione.

9
00:00:24,240 --> 00:00:27,620
‫Quindi questo pezzo di codice che abbiamo scritto nell'ultima

10
00:00:27,620 --> 00:00:31,830
‫lezione, per leggere un file e poi salvarne il contenuto in

11
00:00:31,830 --> 00:00:34,400
‫una variabile, era in un cosiddetto modo

12
00:00:34,400 --> 00:00:36,840
‫sincrono, il che significa semplicemente

13
00:00:36,840 --> 00:00:41,330
‫che ogni istruzione viene fondamentalmente elaborata una dopo l'altra, riga per linea.

14
00:00:41,330 --> 00:00:42,540
‫In questo

15
00:00:42,540 --> 00:00:45,630
‫esempio, prima è richiesto il modulo del file

16
00:00:45,630 --> 00:00:47,630
‫system, quindi il file viene

17
00:00:47,630 --> 00:00:50,900
‫letto e quindi registriamo il risultato nella console.

18
00:00:50,900 --> 00:00:53,340
‫Quindi vedi che ogni riga

19
00:00:53,340 --> 00:00:57,340
‫di codice sostanzialmente attende il risultato della riga precedente.

20
00:00:57,340 --> 00:00:59,440
‫Ora, questo può diventare un

21
00:00:59,440 --> 00:01:01,500
‫problema, specialmente con operazioni lente,

22
00:01:01,500 --> 00:01:04,190
‫perché ogni riga blocca l'esecuzione del resto

23
00:01:04,190 --> 00:01:05,710
‫del codice.

24
00:01:05,710 --> 00:01:08,120
‫E quindi diciamo che il

25
00:01:08,120 --> 00:01:12,290
‫codice sincrono è anche chiamato codice di blocco perché, ancora una

26
00:01:12,290 --> 00:01:15,080
‫volta, una certa operazione può essere eseguita

27
00:01:15,080 --> 00:01:17,740
‫solo dopo che quella precedente è terminata.

28
00:01:17,740 --> 00:01:20,850
‫E a causa del modo in cui Node. js è stato

29
00:01:20,850 --> 00:01:24,220
‫progettato, questo si trasforma in un grosso problema, come

30
00:01:24,220 --> 00:01:26,190
‫vedremo in dettaglio nella prossima slide.

31
00:01:26,190 --> 00:01:28,500
‫Quindi la soluzione a questo

32
00:01:28,500 --> 00:01:32,160
‫problema in Node è usare codice asincrono e non bloccante.

33
00:01:32,160 --> 00:01:35,380
‫Quindi, nel codice asincrono, carichiamo un lavoro pesante

34
00:01:35,380 --> 00:01:38,470
‫su cui lavorare sostanzialmente in background.

35
00:01:38,470 --> 00:01:40,820
‫E poi, una volta terminato

36
00:01:40,820 --> 00:01:43,370
‫il lavoro, viene chiamata una funzione di callback

37
00:01:43,370 --> 00:01:45,730
‫che registriamo prima per gestire il risultato.

38
00:01:45,730 --> 00:01:47,540
‫E durante tutto questo

39
00:01:47,540 --> 00:01:50,380
‫tempo, il resto del codice può ancora

40
00:01:50,380 --> 00:01:52,910
‫essere eseguito senza essere bloccato dall'attività

41
00:01:52,910 --> 00:01:55,820
‫pesante, che ora è in esecuzione in background.

42
00:01:55,820 --> 00:01:59,520
‫Quindi ciò significa che possiamo effettivamente rinviare o

43
00:01:59,520 --> 00:02:01,620
‫reagire al futuro

44
00:02:01,620 --> 00:02:04,530
‫per rendere il codice non bloccante

45
00:02:04,530 --> 00:02:07,676
‫e questo, ovviamente, è molto meglio.

46
00:02:07,676 --> 00:02:09,287
‫Ha senso?

47
00:02:09,287 --> 00:02:12,203
‫Quindi, in questo esempio, usiamo la

48
00:02:12,203 --> 00:02:16,390
‫funzione asincrona readFile, che accetta una funzione di callback.

49
00:02:16,390 --> 00:02:19,120
‫Questo inizierà a leggere il file

50
00:02:19,120 --> 00:02:22,360
‫in background per poi passare immediatamente all'istruzione successiva,

51
00:02:22,360 --> 00:02:25,830
‫stampando sulla console il file di lettura delle stringhe.

52
00:02:25,830 --> 00:02:30,530
‫Quindi, di nuovo, vedete, non stiamo bloccando l'esecuzione qui.

53
00:02:30,530 --> 00:02:33,860
‫Quindi, quando il file sarà finalmente letto completamente, verrà chiamata

54
00:02:33,860 --> 00:02:35,870
‫la funzione di callback, e

55
00:02:35,870 --> 00:02:38,100
‫così, i dati che erano stati

56
00:02:38,100 --> 00:02:40,270
‫letti verranno quindi stampati sulla console.

57
00:02:40,270 --> 00:02:41,890
‫Quindi è abbastanza diverso

58
00:02:41,890 --> 00:02:43,893
‫dalla versione sincrona, non è vero?

59
00:02:44,870 --> 00:02:46,710
‫Ora, la domanda qui

60
00:02:46,710 --> 00:02:49,490
‫è, perché in realtà deve essere così?

61
00:02:49,490 --> 00:02:53,940
‫Qual è il problema con il blocco dell'esecuzione del codice in Node. js?

62
00:02:53,940 --> 00:02:57,030
‫O, in altre parole, perché utilizziamo effettivamente il callback così

63
00:02:57,030 --> 00:02:59,770
‫tante volte in Node. js?

64
00:02:59,770 --> 00:03:01,523
‫Bene, scopriamolo.

65
00:03:03,110 --> 00:03:05,930
‫E per capire queste domande, la prima cosa

66
00:03:05,930 --> 00:03:08,220
‫che dobbiamo capire è il fatto

67
00:03:08,220 --> 00:03:11,260
‫che un Node. js, che è

68
00:03:11,260 --> 00:03:13,760
‫dove è in esecuzione la nostra

69
00:03:13,760 --> 00:03:16,410
‫applicazione, c'è solo un singolo thread.

70
00:03:16,410 --> 00:03:19,720
‫E il thread è proprio come una serie di istruzioni

71
00:03:19,720 --> 00:03:22,200
‫che viene eseguita nella CPU del computer.

72
00:03:22,200 --> 00:03:25,200
‫Quindi, in pratica, il thread è il punto

73
00:03:25,200 --> 00:03:29,270
‫in cui il nostro codice viene effettivamente eseguito nel processore di una macchina.

74
00:03:29,270 --> 00:03:33,120
‫Quindi, ricorda, Node. js è fondamentalmente a

75
00:03:33,120 --> 00:03:36,980
‫thread singolo e quindi, per ogni applicazione, c'è solo un thread.

76
00:03:36,980 --> 00:03:40,300
‫Questo è il modo in cui Node. js è stato progettato.

77
00:03:40,300 --> 00:03:43,050
‫Ora, ciò significa che tutti gli

78
00:03:43,050 --> 00:03:46,960
‫utenti che accedono alla tua applicazione utilizzano tutti lo stesso

79
00:03:46,960 --> 00:03:50,040
‫thread, quindi, in pratica, accedono allo stesso thread.

80
00:03:50,040 --> 00:03:53,410
‫E così, ogni volta che interagiscono con l'applicazione,

81
00:03:53,410 --> 00:03:55,860
‫il codice che viene eseguito

82
00:03:55,860 --> 00:03:59,810
‫per ogni utente verrà eseguito tutto nello stesso thread nella

83
00:03:59,810 --> 00:04:02,490
‫stessa posizione nel computer che esegue l'applicazione.

84
00:04:02,490 --> 00:04:04,900
‫E questo è vero non importa

85
00:04:04,900 --> 00:04:09,900
‫se hai cinque utenti, come in questo diagramma, o 5.000 o 5 milioni.

86
00:04:10,610 --> 00:04:12,080
‫Tutto ok?

87
00:04:12,080 --> 00:04:15,310
‫Ora, ciò significa anche che quando un utente

88
00:04:15,310 --> 00:04:17,960
‫blocca il singolo thread con codice

89
00:04:17,960 --> 00:04:19,640
‫sincrono, come abbiamo

90
00:04:19,640 --> 00:04:22,280
‫appena visto prima, tutti gli altri

91
00:04:22,280 --> 00:04:24,680
‫utenti dovranno attendere il termine dell'esecuzione.

92
00:04:24,680 --> 00:04:27,010
‫E questo potrebbe non essere un

93
00:04:27,010 --> 00:04:29,800
‫grosso problema se hai come cinque utenti, ma

94
00:04:29,800 --> 00:04:33,350
‫sicuramente lo sarà per migliaia o addirittura milioni di

95
00:04:33,350 --> 00:04:35,393
‫utenti allo stesso tempo.

96
00:04:36,440 --> 00:04:39,830
‫Quindi, immagina che un utente stia accedendo alla tua applicazione

97
00:04:39,830 --> 00:04:43,280
‫e che ci sia un enorme file sincrono letto nel

98
00:04:43,280 --> 00:04:46,630
‫tuo codice che impiegherà un secondo per caricarsi.

99
00:04:46,630 --> 00:04:49,920
‫Ciò significa, ovviamente, che per quel secondo,

100
00:04:49,920 --> 00:04:52,370
‫tutti gli altri utenti

101
00:04:52,370 --> 00:04:57,370
‫dovranno aspettare perché l'intera esecuzione è bloccata per quel secondo.

102
00:04:57,490 --> 00:05:00,680
‫Quindi, se quegli altri utenti vogliono svolgere alcune semplici

103
00:05:00,680 --> 00:05:02,940
‫attività, come accedere alla tua applicazione

104
00:05:02,940 --> 00:05:06,900
‫o semplicemente richiedere alcuni dati, non saranno in grado di farlo.

105
00:05:06,900 --> 00:05:11,150
‫Dovranno attendere che il file finisca di leggere.

106
00:05:11,150 --> 00:05:15,130
‫Solo quando ciò accadrà saranno finalmente in grado di svolgere

107
00:05:15,130 --> 00:05:18,113
‫i compiti più semplici, uno dopo l'altro.

108
00:05:19,260 --> 00:05:23,290
‫Ora, tieni presente che questa è una versione molto semplificata di ciò che accade

109
00:05:23,290 --> 00:05:27,010
‫davvero dietro le quinte di Node. js, motivo per

110
00:05:27,010 --> 00:05:29,880
‫cui torneremo su tutto questo nella

111
00:05:29,880 --> 00:05:33,760
‫prossima sezione e avremo una comprensione ancora più

112
00:05:33,760 --> 00:05:38,090
‫profonda di come Node. js gestisce il codice asincrono sotto il cofano.

113
00:05:38,090 --> 00:05:39,370
‫Ma a questo

114
00:05:39,370 --> 00:05:42,170
‫punto ti basta questo per capire il concetto.

115
00:05:42,170 --> 00:05:44,560
‫È meglio procedere passo dopo

116
00:05:44,560 --> 00:05:46,520
‫passo e non

117
00:05:46,520 --> 00:05:49,220
‫creare confusione fin dall'inizio, ok?

118
00:05:49,220 --> 00:05:51,660
‫Ad ogni modo, è così che

119
00:05:51,660 --> 00:05:54,620
‫andrebbe a finire la situazione con il codice di

120
00:05:54,620 --> 00:05:58,460
‫blocco sincrono, che è ovviamente un'esperienza terribile per i tuoi utenti.

121
00:05:58,460 --> 00:06:01,180
‫Quindi, è davvero il tuo lavoro come

122
00:06:01,180 --> 00:06:03,260
‫sviluppatore evitare questo tipo di

123
00:06:03,260 --> 00:06:05,113
‫situazioni utilizzando codice asincrono.

124
00:06:07,150 --> 00:06:10,180
‫Quindi, per la stessa situazione, dovremmo, ovviamente, usare la

125
00:06:10,180 --> 00:06:12,780
‫funzione di lettura file asincrona, che invece

126
00:06:12,780 --> 00:06:15,190
‫di bloccare il singolo thread,

127
00:06:15,190 --> 00:06:17,700
‫fa il lavoro pesante in background, dove

128
00:06:17,700 --> 00:06:20,170
‫sostanzialmente rimane fino a quando non ha

129
00:06:20,170 --> 00:06:22,700
‫finito di leggere i dati dal file.

130
00:06:22,700 --> 00:06:25,950
‫Ovviamente poi registriamo anche una funzione di callback

131
00:06:25,950 --> 00:06:29,490
‫da richiamare una volta che i dati sono disponibili.

132
00:06:29,490 --> 00:06:32,130
‫E in questo scenario, tutti gli altri

133
00:06:32,130 --> 00:06:35,100
‫utenti possono quindi svolgere le loro attività in

134
00:06:35,100 --> 00:06:38,710
‫un singolo thread, uno dopo l'altro, mentre il file viene

135
00:06:38,710 --> 00:06:40,390
‫ancora letto in background.

136
00:06:40,390 --> 00:06:43,870
‫Ora, una volta letti i dati, la nostra funzione

137
00:06:43,870 --> 00:06:46,240
‫di callback verrà ovviamente chiamata

138
00:06:46,240 --> 00:06:51,240
‫per essere eseguita nel singolo thread principale per elaborare i dati letti.

139
00:06:51,380 --> 00:06:52,460
‫E questo è tutto.

140
00:06:52,460 --> 00:06:54,720
‫Questa è una panoramica di come Node. js gestisce

141
00:06:54,720 --> 00:06:58,000
‫il comportamento asincrono per implementare il modello di

142
00:06:58,000 --> 00:07:00,850
‫I/O non bloccante di cui abbiamo

143
00:07:00,850 --> 00:07:03,670
‫parlato nella lezione introduttiva, va bene?

144
00:07:03,670 --> 00:07:07,240
‫E I/O sta semplicemente per input-output, che è

145
00:07:07,240 --> 00:07:10,810
‫fondamentalmente cose come accedere al file system e

146
00:07:10,810 --> 00:07:13,500
‫gestire le richieste di rete.

147
00:07:13,500 --> 00:07:16,470
‫Questo è in realtà l'intero motivo per cui Node. js è

148
00:07:16,470 --> 00:07:18,830
‫completamente progettato attorno ai callback,

149
00:07:18,830 --> 00:07:21,190
‫come vedrai durante il corso.

150
00:07:21,190 --> 00:07:24,090
‫In altri linguaggi di programmazione, come PHP, funziona

151
00:07:24,090 --> 00:07:27,260
‫in modo molto diverso perché ottieni, in pratica, un

152
00:07:27,260 --> 00:07:29,640
‫nuovo thread per ogni nuovo utente,

153
00:07:29,640 --> 00:07:32,020
‫che è un paradigma completamente diverso

154
00:07:32,020 --> 00:07:34,600
‫e funziona davvero in modo completamente diverso.

155
00:07:34,600 --> 00:07:37,620
‫Ma il creatore di Node. js ha scoperto che

156
00:07:37,620 --> 00:07:40,660
‫questo modello è la soluzione migliore per la creazione

157
00:07:40,660 --> 00:07:42,980
‫di applicazioni Web altamente performanti e scalabili.

158
00:07:42,980 --> 00:07:46,810
‫Ora, solo come nota finale qui, è importante sapere che,

159
00:07:46,810 --> 00:07:48,830
‫quando usiamo i callback

160
00:07:48,830 --> 00:07:53,380
‫nel nostro codice, ciò non lo rende automaticamente asincrono, va bene?

161
00:07:53,380 --> 00:07:56,520
‫Quindi, passare le funzioni ad altre funzioni

162
00:07:56,520 --> 00:07:58,780
‫è abbastanza comune in

163
00:07:58,780 --> 00:08:01,830
‫JavaScript, ma ovviamente, ancora una volta,

164
00:08:01,830 --> 00:08:05,110
‫ciò non le rende automaticamente asincrone, ok?

165
00:08:05,110 --> 00:08:09,150
‫Funziona in questo modo solo per alcune funzioni nell'API Node,

166
00:08:09,150 --> 00:08:11,210
‫come la funzione readFile e

167
00:08:11,210 --> 00:08:14,823
‫molte, molte altre, come le persone esploreranno in futuro.

168
00:08:16,610 --> 00:08:18,500
‫E ora, giusto per

169
00:08:18,500 --> 00:08:21,200
‫finire, visto che qui stiamo parlando di

170
00:08:21,200 --> 00:08:24,630
‫codice asincrono, solo un'ultima nota sulle funzioni di callback.

171
00:08:24,630 --> 00:08:27,670
‫Quindi, questo modello di callback di cui abbiamo appena

172
00:08:27,670 --> 00:08:29,370
‫discusso, in cui una

173
00:08:29,370 --> 00:08:32,300
‫funzione viene chiamata una volta che quella precedente ha

174
00:08:32,300 --> 00:08:36,970
‫terminato il suo lavoro, può portare rapidamente a codice difficile da leggere e ingestibile.

175
00:08:36,970 --> 00:08:39,830
‫Prendi questo esempio in cui il secondo file

176
00:08:39,830 --> 00:08:41,870
‫letto dipende dal primo,

177
00:08:41,870 --> 00:08:44,800
‫quindi il terzo file letto dipende dal secondo

178
00:08:44,800 --> 00:08:47,560
‫e, infine, vogliamo utilizzare i dati finali

179
00:08:47,560 --> 00:08:49,700
‫per scrivere un file come risultato.

180
00:08:49,700 --> 00:08:52,690
‫Sembra abbastanza confuso, vero?

181
00:08:52,690 --> 00:08:54,950
‫Voglio dire, funzionerà bene, ma

182
00:08:54,950 --> 00:08:57,330
‫è solo difficile ragionare e questo

183
00:08:57,330 --> 00:09:00,110
‫è solo con quattro livelli di profondità.

184
00:09:00,110 --> 00:09:02,980
‫Immagina di avere 10 o 20 livelli, il

185
00:09:02,980 --> 00:09:05,850
‫che in realtà non è così raro.

186
00:09:05,850 --> 00:09:09,440
‫Comunque, questo è quello che chiamiamo l'inferno del richiamo.

187
00:09:09,440 --> 00:09:11,370
‫È un problema così

188
00:09:11,370 --> 00:09:13,780
‫comune che ha già un nome.

189
00:09:13,780 --> 00:09:16,920
‫E notate questa forma triangolare qui?

190
00:09:16,920 --> 00:09:20,840
‫È un segno molto chiaro che sei nell'inferno delle richiamate.

191
00:09:20,840 --> 00:09:24,350
‫Ora, come possiamo effettivamente sfuggire all'inferno delle richiamate?

192
00:09:24,350 --> 00:09:27,600
‫Bene, possiamo usare strumenti più avanzati per la

193
00:09:27,600 --> 00:09:30,730
‫gestione del codice asincrono, come le

194
00:09:30,730 --> 00:09:34,150
‫promesse di ES6 o anche meglio, async/await di ES8.

195
00:09:34,150 --> 00:09:36,320
‫Ora, il modello di cui abbiamo appena

196
00:09:36,320 --> 00:09:37,890
‫parlato sarà sempre lo stesso.

197
00:09:37,890 --> 00:09:39,960
‫Abbiamo solo modi più

198
00:09:39,960 --> 00:09:43,370
‫eleganti per gestire il codice stesso e scriverlo.

199
00:09:43,370 --> 00:09:45,830
‫E c'è un'intera sezione facoltativa

200
00:09:45,830 --> 00:09:50,090
‫più avanti nel corso sulle promesse e anche, async/await, quindi nel

201
00:09:50,090 --> 00:09:52,590
‫caso tu non abbia familiarità con loro.

202
00:09:52,590 --> 00:09:55,140
‫Ma per ora, continueremo a utilizzare i callback

203
00:09:55,140 --> 00:09:57,900
‫perché questo è ciò che Node utilizzava originariamente ed

204
00:09:57,900 --> 00:10:00,100
‫è stato progettato attorno a questo.

205
00:10:00,100 --> 00:10:02,030
‫E ora, detto questo,

206
00:10:02,030 --> 00:10:05,240
‫andiamo avanti e usiamo questo modello asincrono in

207
00:10:05,240 --> 00:10:07,233
‫pratica per la prima volta.

