Skip to content

Commit 5a524e0

Browse files
Update article.md
Definitivo
1 parent 7cf48de commit 5a524e0

File tree

1 file changed

+49
-49
lines changed

1 file changed

+49
-49
lines changed

2-ui/99-ui-misc/03-event-loop/article.md

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@
33

44
Sia il flusso di esecuzione di Javascript, che quello di Node.js, sono basati sull' *event loop*.
55

6-
Comprendere come funziona un event loop è importante sia per una question di ottimizzazione dell'esecuzione del codice, ma a volte, anche per creare delle architetture migliori.
6+
Comprendere come funziona un event loop è importante sia per una questione di ottimizzazione dell'esecuzione del codice, ma a volte, anche per creare delle architetture software migliori.
77

8-
In questo capitolo affronteremo l dettagli teorici sul funzionanento, dopodichè prenderemo in esame alcune applicazioni pratiche.
8+
In questo capitolo affronteremo i dettagli teorici sul funzionanento, dopodichè prenderemo in esame alcune applicazioni pratiche.
99

1010
## Event Loop
1111

12-
Il concetto di *event loop* è molto semplice. Esiste un loop infinito, nel quale il motore di Javascript rimane in attesa di un task (compito, operazione) da eseguire, lo esegue, dopodichè si rimette in attesa per altri tasks. (rimane in sleep, inattivo o dormiente, ma pronto per essere di nuovo richiamato).
12+
Il concetto di *event loop* è molto semplice. Esiste un loop infinito, nel quale il motore di Javascript rimane in attesa di un task (compito o operazione da eseguire), lo esegue, quindi si mette in attesa per altri tasks (rimane in sleep, inattivo o dormiente, ma pronto per essere di nuovo richiamato).
1313

1414
A grandi linee, l'algoritmo del motore è così:
1515
1. Fino a quando ci sono task:
1616
- eseguili, cominciando da quello meno recente.
1717
2. Rimani in attesa fino a quando non c'è un altro task da eseguire, quindi vai al passo 1.
1818

19-
Questa è una trasposizione di quello che vediamo quando navighiamo in una pagina web. Il motore di Javascript non fa nulla per la maggior parte del tempo, e va in esecuzione quando si attiva uno script/handler/evento.
19+
Questa è una trasposizione di quello che vediamo mentre navighiamo in una pagina web. Il motore di Javascript non fa nulla per la maggior parte del tempo, e va in esecuzione quando si attiva uno script/handler/evento.
2020

2121
Esempio di tasks:
2222

@@ -44,30 +44,30 @@ Ancora due dettagli:
4444
1. Il rendering non avviene mai quando il motore sta eseguendo un task. Non importa se questo impiega molto tempo. I cambiamenti al DOM vengono renderizzati (ridisegnati sul browser) solo dopo che il task viene completato.
4545
2. Se un task impiega troppo tempo, il browser non puiò eseguire altri tasks, processare altri eventi utente, e così dopo un certo periodo di tempo viene scaturito un alert di "Pagina bloccata" (Page Unresponsive) che ci suggerisce di terminare il task e l'intera pagina. Questo succede in concomitanza di una serie di calcoli complessi, o in seguito ad errori di programmazione che portano loop infiniti.
4646

47-
Questa era la teoria, ma vediamo come applicare questi concetti.
47+
Ok, questa era la teoria, ma vediamo come mettere in pratica questi concetti.
4848

4949
## Caso d'uso 1: Spezzettamento di task affamati di CPU (processi intensivi)
5050

51-
Poniamo il caso che abbiamo un task affamato di CPU.
51+
Poniamo il caso che abbiamo un task affamato di CPU (CPU-hungry process).
5252

5353
Per esempio, la syntax-highlighting (usata per colorare ed evidenziare gli esempi del codice in questa pagina) è abbastanza pesante per la CPU.
5454
Per evidenziare il codice, compie delle analisi, crea molti elementi colorati, e li aggiunge al documento -- un testo di grosse dimensioni può impiegare molto tempo.
5555

56-
Mentre il motore è occupato con l'evidenziatura, non può fare le altre cose relative al DOM, processare gli eventi dell'utente, etc. può persino causare "singhiozzamenti" al pc o addirittura "inchiodarlo", la qual cosa è inaccettabile.
56+
Mentre il motore è occupato con l'evidenziatura, non può fare altre cose relative al DOM, processare gli eventi dell'utente, etc. può, può persino causare "singhiozzamenti" al pc o addirittura "inchiodarlo", la qual cosa è inaccettabile.
5757

58-
Possiamo quindi tirarci fuori da questo tipo di problemi, spezzettando i task grossi in piccoli pezzi. Evidenzia le prime 100 righe, quindi schedula un `setTimeout` (con zero-delay) con altre 100 righe, e così via fino alla fine.
58+
Possiamo quindi tirarci fuori da questo tipo di problemi, spezzettando i task grossi in piccoli pezzi da eseguire. Evidenzia le prime 100 righe, quindi schedula un `setTimeout` (con zero-delay) con altre 100 righe, e così via fino alla fine.
5959

6060
Per dimostrare questo tipo di approccio, e per amore della semplicità, anzichè evidenziare una sintassi, prendiamo una funzione che conti i numeri da `1` a `1000000000`
6161

62-
Se esegui il codice sotto, il motore si inchioderà per qualche istante. Per il JS server-side (lato server) questo è chiaramente visibile, ma se lo stai eseguendo nella finestra del browser, provando a cliccare gli altri pulsanti -- potrai notare che non verrà gestito nessun altro evento fino a quando il conto non sarà terminato.
62+
Se esegui il codice sotto, il motore si inchioderà per qualche istante. Per il JS server-side (lato server) questo è chiaramente visibile, ma se lo stai eseguendo nella finestra del browser, provando a cliccare gli altri pulsanti -- potrai notare che non verrà gestito nessun altro evento fino a quando il conteggio dei numeri non sarà terminato.
6363

6464
```js run
6565
let i = 0;
6666

6767
let start = Date.now();
6868

6969
function count() {
70-
//fa un lavoro pesante!
70+
//un lavoro pesante!
7171
for (let j = 0; j < 1e9; j++) {
7272
i++;
7373
}
@@ -80,15 +80,15 @@ count();
8080
Il browser potrebbe anche mostrare l'avviso "lo script sta impiegando troppo tempo" the script takes too long".
8181

8282

83-
Ora, dividiamo l'operazione con l'ausilio di un `setTimeout` annidato:
83+
Ora invece, dividiamo l'operazione con l'ausilio di un `setTimeout` annidato:
8484

8585
```js run
8686
let i = 0;
8787

8888
let start = Date.now();
8989

9090
function count() {
91-
//fai una parte del lavoro pesante (*)
91+
//fai una parte del lavoro pesante :-) (*)
9292
do {
9393
i++;
9494
} while (i % 1e6 != 0);
@@ -110,13 +110,13 @@ Una singola esecuzione di `count` fa una parte dell'operazione `(*)`, e rischedu
110110
2. La seconda esecuzione conta: `i=1000001..2000000`.
111111
3. ...e cos&igrave; via.
112112

113-
Ora, se arriva un nuovo task da eseguire mentre il motore &egrave; occupato ad eseguire il passo 1 (ad esempio un evento `onclick`), quest'ultimo viene messo in coda e viene eseguito subito dopo il completamento del passo 1, e subito prima del passo successivo. Questi periodici "ritorni" all'event loop tra una esecuzione di `count` e l'altra, fornisce abbastanza "aria" al motore Javascript per occuparsi di qualcos'altro, ad esempio per reagire alle azioni degli utenti.
113+
Ora, se arriva un nuovo task da eseguire mentre il motore &egrave; occupato ad eseguire il passo 1, poniamo il caso ad esempio che venga sollevato un evento `onclick`, quest'ultimo viene messo in coda ed eseguito subito dopo il completamento del passo 1, ma subito prima del passo successivo. Questi periodici "ritorni" all'event loop tra una esecuzione di `count` e l'altra, fornisce abbastanza "respiro" al motore Javascript per occuparsi di qualcos'altro, ad esempio per reagire alle azioni degli utenti.
114114

115115
La cosa ragguardevole &egrave; che entrambe le varianti -- con e senza la divsione del lavoro di `setTimeout` -- sono comparabili in termini di tempo. Complessivamente, non esiste molta differenza nel tempo di conteggio.
116116

117-
Per renderli un po' pi&ugrave; facciamo un miglioramento.
117+
Per renderli un po' pi&ugrave; più comparabili, facciamo un miglioramento.
118118

119-
Posizioneremo la schedualzione all'inizio del `count()`:
119+
Posizioniamo la schedulazione all'inizio del `count()`:
120120

121121

122122
```js run
@@ -139,25 +139,26 @@ function count() {
139139
count();
140140
```
141141

142-
Adesso quando cominciamo con `count()` e vediamo che abbiamo bisogno di richiamarlo pi&ugrave; `count()`, lo scheduliamo subito, prima di fare il lavoro.
142+
Adesso, quando cominciamo con `count()` e vediamo che abbiamo bisogno di richiamarlo pi&ugrave; `count()`, lo scheduliamo subito prima di fare il lavoro.
143143

144-
Se lo esegui, &egrave; facile notare che impiega meno tempo in modo significativo.
144+
Se lo esegui, &egrave; facile notare che impiega significativamente meno tempo.
145145

146146

147147
Perch&egrave;?
148148

149-
Semplice: come ben sai, c'&egrave; un ritardo minimo di 4ms all'interno del browser per molte chiamate annidate di `setTimeout`. Anche se noi lo settiamo `0`, sar&agrave; di `4ms` (o qualcosa in pi&ugrave). Quindi, prima lo scheduliamo, pi&ugrave; veloce sar&agrave; l'esecuzione.
150-
Alla fine, abbiamo diviso un task affamato di CPU in porzioni - e adesso non bloccher&agrave; l'interfaccia utente. E il suo tempo di esecuzione complessivo non &egrave; tanto pi&ugrave; lungo.
149+
Semplice: come saprai, c'&egrave; un ritardo minimo di 4ms all'interno del browser per tantissime chiamate annidate di `setTimeout`. Anche se noi lo abbiamo impostato a `0`, sar&agrave; di `4ms` (o qualcosa in pi&ugrave). Quindi, prima lo scheduliamo, pi&ugrave; veloce sar&agrave; l'esecuzione.
150+
Alla fine, abbiamo diviso un task affamato di CPU in porzioni - che adesso non bloccher&agrave; pi&ugrave; l'interfaccia utente. Inoltre, il suo tempo di esecuzione complessivo non &egrave; tanto pi&ugrave; lungo.
151+
151152

152153
## Caso d'uso 2: Indicazione dei progressi di una operazione
153154

154-
Un altro beneficio di dividere task pesanti per gli script del browser &egrave; che possiamo mostrare i progressi di completamento.
155+
Un altro beneficio nel dividere task pesanti per gli script del browser &egrave; che possiamo mostrare i progressi di completamento.
155156

156157
Solitamente il browser renderizza dopo che il codice in esecuzine viene completato. Non importa se il task impiega tanto tempo. Le modifice al DOM vengono mostrate solo dopo che il task &egrave; terminato.
157158

158-
Da una parte, questo &egrave; grandioso, perch&egrave; la nostra fuznione pu&ograve; molti elementi, aggiungerli uno alla volta al documento e cambiarne gli stili -- il visitatore non vorrebbe mai vedere uno stadio "intermedio", incompleto. Una cosa importante, giusto?
159+
Da una parte, questo &egrave; grandioso, perch&egrave; la nostra funzione pu&ograve; creare molti elementi, aggiungerli uno alla volta al documento e cambiarne gli stili -- il visitatore, d'altra parte, non vorrebbe mai vedere uno stadio "intermedio" ed incompleto. Una cosa importante, giusto?
159160

160-
Qui c'&egrave; la demo, i cambiamenti a `i` non verrano mostrati fino a quando la funzione nno termina, cos&igrave; vedremo solamente l'ultimo valore:
161+
Con l'esempio qui sotto abbiamo una dimostrazione, le modifiche all'elemento che rappresenta i valori di `i` non verrano mostrati fino a quando la funzione non termina, cos&igrave; vedremo solamente il valore definitivo:
161162

162163
```html run
163164
<div id="progress"></div>
@@ -175,9 +176,9 @@ Qui c'&egrave; la demo, i cambiamenti a `i` non verrano mostrati fino a quando l
175176
</script>
176177
```
177178

178-
...Per&ograve; potremmo volere mostrare qualcosa durante il task, ad esempio una barra di progresso.
179+
...Tuttavia; potremmo voler mostrare qualcosa durante il task, ad esempio una barra di progresso.
179180

180-
Se noi dividiamo il task pesante in pezzi usando `setTimeout`, allora tra essi, verranno mostrate le variazioni.
181+
Se andiamo a dividere il task pesante in pezzi usando `setTimeout`, allora tra ognuno di essi, verranno mostrate delle variazioni.
181182

182183
Questo sembra pi&ugrave; carino:
183184

@@ -205,21 +206,20 @@ Questo sembra pi&ugrave; carino:
205206
</script>
206207
```
207208

208-
Adesso il `<div>` mostra via via, valori crescenti di `i`,come se fosse una sorta di barra di caricamento.
209+
Adesso il `<div>` mostra valori sempre crescenti di `i`, come se fosse una sorta di barra di caricamento.
209210

210211

211212
## Caso d'uso 3: fare qualcosa dopo l'evento
212213

213-
In un gestore di evento, potremmo decidere di postporre alcune azioni, fino a che l'evento non risalga i vari livelli di stack (bubbling up) e non venga gestito su tutti questi livelli.
214-
Possiamo farlo, avvolgendo (wrapping) il codice all'interno dei `setTimeout` a ritardo zero.
214+
In un gestore di evento, potremmo decidere di postporre alcune azioni, fino a che l'evento non risalga i vari livelli dello stack (bubbling up) e non venga gestito su tutti questi livelli.
215+
Possiamo farlo, avvolgendo (wrapping) il codice all'interno di istruzioni `setTimeout` a ritardo zero.
215216

216-
Nel capitolo <info:dispatch-events> abbiamo visto un esempio: dell'evento custom `menu-open`, viene fatto il dispatch dentro `setTimeout`, cos&igrave; che esso viene richiamato dopo che l'evento click &egrave; stto del tutto gestito.
217+
Nel capitolo <info:dispatch-events> abbiamo visto un esempio: dell'evento custom `menu-open`, viene fatto il dispatch dentro `setTimeout`, cos&igrave; che esso viene richiamato dopo che l'evento click &egrave; stato del tutto gestito.
217218

218219

219220
```js
220221
menu.onclick = function() {
221222
// ...
222-
223223
//crea un evento custom con l'elemento dati cliccato sul menu'
224224
let customEvent = new CustomEvent("menu-open", {
225225
bubbles: true
@@ -230,16 +230,16 @@ menu.onclick = function() {
230230
};
231231
```
232232

233-
## Macrotasks e Microtasks
234233

234+
## Macrotasks e Microtasks
235235

236-
insieme ai *macrotasks*, descritti in questo capitolo, esistono i *microtasks*, menzionati nel capitolo <info:microtask-queue>.
236+
Insieme ai *macrotasks*, descritti in questo capitolo, esistono i *microtasks*, menzionati nel capitolo <info:microtask-queue>.
237237

238-
Microtasks provengono esclusivamente dal nostro codice. Solitamente vengono creati dalle promises: una esecuzione di un gestore `.then/catch/finally` diventa un microtask. I microtasks vengono usati anche "sotto copertura" dagli `await`, dato che anche questi sono solo un'altra forma di gestione delle promise.
238+
I microtasks provengono esclusivamente dal nostro codice. Solitamente vengono creati dalle promises: una esecuzione di un gestore `.then/catch/finally` diventa un microtask. I microtasks vengono usati anche "sotto copertura" dagli `await`, dato che anche questi non sono altro che un'altra forma di gestione di promises.
239239

240-
C'&egrave; anche una funzione speciale `queueMicrotask(func)` che accoda `func`per l'esecuzione nella coda dei microtask.
240+
C'&egrave; anche una funzione speciale `queueMicrotask(func)` che accoda `func` per l'esecuzione nella coda dei microtask.
241241

242-
**Immediatamente dopo ogni *macrotask*, il motore esegue tutti i task dalla coda *microtask* queue, prima di ricominciare a eseguire ogni altro macrotask o renderizzare o qualunque altra cosa.**
242+
**Immediatamente dopo ogni *macrotask*, il motore esegue tutti i task dalla coda *microtask*, prima di ricominciare a eseguire ogni altro macrotask o renderizzare o qualunque altra cosa.**
243243

244244
Per esempio, guardate questo:
245245

@@ -252,24 +252,24 @@ Promise.resolve()
252252
alert("code");
253253
```
254254

255-
Che sta succedendo all'ordine qui?
255+
Cosa succeder&agrave; all'ordine delle operazioni in questo script?
256256

257-
1. `code` viene mostrato prima, dato che &egrave; un chiamata regolare e sincrona.
257+
1. `code` viene mostrato per primo, dato che &egrave; un chiamata regolare e sincrona.
258258
2. `promise` viene mostrato per secondo, perch&egrave; `.then` passa attraverso la coda di microtask, e viene eseguito dopo il codice corrente.
259259
3. `timeout` viene mostrato come ultimo perch&egrave; &egrave; anhe questo un microtask.
260260

261-
L'immagine pi&ugrave; esausitva di un event loop &egrave; &egrave; questa:
261+
L'immagine pi&ugrave; esausitva di un event loop &egrave; questa:
262262

263263
![](eventLoop-full.svg)
264264

265265
**Tutti i microtasks vengono completati prima di ogni altra gestione degli eventi o rendering o qualunque altro macrotask che prende parte nell'esecuzione**
266266

267-
Questo &egrave; importante perch&egrave; garantisce che l'ambiente applicativo rimanga intatto (nessuna modifica alle coordinate del puntatore del mouse, nessun dato dalle reti, etc) tra i microtasks.
267+
Questo &egrave; importante perch&egrave; garantisce che l'ambiente applicativo rimanga intatto (nessuna modifica alle coordinate del puntatore del mouse, nessun dato dalle reti, etc) tra i vari microtasks.
268268

269-
Se volessimo eseguire una funzione in maniera asincrona (dopo il codice in esecuzione), ma prima che avvengano cambiamenti nella finestra del browser, o nuvi eventi vengano gestiti, potremmo schedularla con `queueMicrotask`.
269+
Se volessimo eseguire una funzione in maniera asincrona (dopo il codice in esecuzione), ma prima che avvengano cambiamenti nella finestra del browser, o che nuovi eventi vengano gestiti, potremmo schedularla con `queueMicrotask`.
270270

271-
Questo qui un esempio con la "conteggio barra di progresso", del tutto simi a quella precedente, ma vengono usati `queueMicrotask` invece di `setTimeout`.
272-
Come puoi vedere che renderizza alla fine. Esattamente come se fosse del codice sincrono:
271+
Questo qui &egrave; un esempio della funzion "conteggio barra di progresso", del tutto simile alla precedente, ma vengono usati `queueMicrotask` invece di `setTimeout`.
272+
Come puoi notare, renderizza il valore del conteggio alla fine. Esattamente come se fosse del codice sincrono:
273273

274274
```html run
275275
<div id="progress"></div>
@@ -299,7 +299,7 @@ L'immagine pi&ugrave; esausitva di un event loop &egrave; questa:
299299

300300
![](eventLoop-full.svg)
301301

302-
Il pi&ugrave; dettagliato algoritmo dell'event loop (sebbene ancora semplicistico rispetto alla [specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)):
302+
Questo &egrave; il pi&ugrave; dettagliato algoritmo dell'event loop: (sebbene ancora semplicistico rispetto alla [specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)):
303303

304304
1. Rimuovi dalla coda ed esegui il task meno recente dalla coda dei *macrotask* (ad esempio "script").
305305
2. Esegui tutti i *microtasks*:
@@ -310,26 +310,26 @@ Il pi&ugrave; dettagliato algoritmo dell'event loop (sebbene ancora semplicistic
310310
5. Vai al passo 1.
311311

312312
Per schedulare un nuovo *macrotask*:
313-
- Use zero delayed `setTimeout(f)`.
313+
- Usa un `setTimeout(f)` ritardo zero.
314314

315-
Questo potrebbe essere usato per divitere task di calcolopesante in pezzi, di modo che tra questi, il browser possa eseguire altre operazioni.
315+
Questo potrebbe essere usato per divitere task di calcolo pesante in pezzi più piccoli, di modo che nello spazio tra questi, il browser possa eseguire altre operazioni.
316316

317317
Inoltre, vengono usati nei gestori degli eventi per schedulre una azione dopo che l'evento &egrave; stato del tutto gestito (bubbling completato)
318318

319319
Per schedulare un nuovo *microtask*
320320
- Usa `queueMicrotask(f)`.
321321
- Anche i gestori promise passando attraverso la coda dei microtask.
322322

323-
Non ci sono gestori UI o di networking tra i microtask: vengono eseguiti immediatamente uno dopo l'altro
323+
Non ci possono essere gestioni di UI o di networking tra i microtask, perchè i microtasks vengono eseguiti immediatamente uno dopo l'altro.
324324

325-
Quindi uno potrebbe volere che la coda `queueMicrotask` eseguisse una funzione in maniera asincrona, ma manntenendo il contesto dell'ambiente.
325+
Ma cosa succederebbe se uno volesse che la coda `queueMicrotask` eseguisse una funzione in maniera asincrona, mantenendo però il contesto dell'ambiente.
326326

327327
```smart header="Web Workers"
328328
Per lunghi calcoli pesanti che non possono bloccare l'event loop, possiamo usare i [Web Workers](https://html.spec.whatwg.org/multipage/workers.html).
329329
330-
Che &egrave; un modo per eseguire del codice in un altro thread parallelo.
330+
I Web Workers sono un modo per eseguire del codice in un altro thread parallelo.
331331
332-
I Web Workers possono scambiarsi messaggi con il processo principale, ma hanno le loro variabili ed i loro event loop.
332+
I Web Workers possono scambiare messaggi con il processo principale, ma hanno le loro variabili ed i loro event loop.
333333
334-
I Web Workers non hanno accesso al DOM, quindi sono adatti principalmente per i calcoli, per usare contemporaneamente pi&ugrave; cores CPU.
334+
I Web Workers non hanno accesso al DOM, quindi sono adatti principalmente per i calcoli, per usare contemporaneamente pi&ugrave; cores della CPU.
335335
```

0 commit comments

Comments
 (0)