You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 2-ui/99-ui-misc/03-event-loop/article.md
+22-23Lines changed: 22 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,50 +1,50 @@
1
1
2
2
# Event loop: microtasks e macrotasks
3
3
4
-
Il flusso di esecuzione di Javascript, così come quello di Node.js, è basato sull' *event loop*.
4
+
Sia il flusso di esecuzione di Javascript, che quello di Node.js, sono basati sull' *event loop*.
5
5
6
-
Comprendere come funziona un event loop è importante sia per ottimizzazione, ma a volte, anche per creare delle architetture migliori.
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.
7
7
8
-
In questo capitolo affronteremo i dettagli teorici sul funzionanento, dopodichè prenderemo in esame alcune applicazioni pratiche.
8
+
In questo capitolo affronteremo l dettagli teorici sul funzionanento, dopodichè prenderemo in esame alcune applicazioni pratiche.
9
9
10
10
## Event Loop
11
11
12
-
Il concetto di *event loop*è molto semplice. Esiste un loop infinito nel quale il motore di Javascript rimane in attesa di un task (operazione) da eseguire, lo esegue, dopodichè si rimette in attesa per altri tasks. (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, 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).
13
13
14
-
Questo, è a grandi linee, l'algoritmo del motore:
14
+
A grandi linee, l'algoritmo del motoreè così:
15
15
1. Fino a quando ci sono task:
16
16
- eseguili, cominciando da quello meno recente.
17
17
2. Rimani in attesa fino a quando non c'è un altro task da eseguire, quindi vai al passo 1.
18
18
19
-
Questa è una esposizione di quello che vediamo quando navighiamo una pagina. 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 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.
20
20
21
21
Esempio di tasks:
22
22
23
-
- Quando uno script esterno `<script src="...">` viene caricato (load), il task è quello di eseguirlo.
24
-
- Quando un utente sposta il puntatore del mouse, il task è quello di fare il dispatch dell'evento `mousemove` ed eseguirne eventuali handlers (gestori).
23
+
- Quando viene caricato uno script esterno `<script src="...">` (load), il task è quello di eseguirlo.
24
+
- Quando un utente sposta il puntatore del mouse, il task è quello di lanciare il dispatch dell'evento `mousemove` ed eseguirne eventuali handlers (gestori).
25
25
- Quando è scaduto il tempo per `setTimeout` già schedulato, il task è quello di eseguirne la callback.
26
26
- ...e così via.
27
27
28
-
I task vengono impostati -- il motore li gestisce -- quindi rimane in attesa per altri tasks (nel frattempo rimane in sleep, consumando risorse della CPU prossime allo zero).
28
+
I task vengono impostati -- il motore li gestisce -- quindi rimane in attesa per altri tasks (nel frattempo rimane in sleep, consumando risorse CPU prossime allo zero).
29
29
30
30
Però potrebbe succedere che mentre il motore è occupato, arrivi un task, in questo caso, questo viene messo in coda.
31
31
32
-
I task formano una coda, la cosiddetta "macrotask queue" (termine mutuato V8, il motore Javascript di Chrome e di Node.js):
32
+
I task formano una coda, la cosiddetta "macrotask queue" (termine mutuato da V8, il motore Javascript di Chrome e di Node.js):
33
33
34
34

35
35
36
-
Ad esempio, se mentre il motore è occupato nell'esecuzione di uno `script`, l'utente muove il mouse generando un `mousemove`, e magari nello stesso istante è scaduto il tempo di un `setTimeout`, questi task formano una queue (una coda di esecuzione) come illustrato nella figura di sopra.
36
+
Ad esempio se, mentre il motore è occupato nell'esecuzione di uno `script`, l'utente muove il mouse generando un `mousemove`, e magari nello stesso istante è scaduto il tempo di un `setTimeout`, questi task formano una queue (una coda di esecuzione) come illustrato nella figura appena sopra.
37
37
38
-
I task dalla coda vengono processati sulla base del "first come – first served", cioè secondo l'ordine che il primo arrivato sarà il primo ad essere servito (FIFO).
39
-
Quando il motere del browser avrà terminato con lo `script`, gestirà l'evento `mousemove`, quindi si occuperà del gestore del `setTimeout` (la callback), e così
38
+
I tasks dalla coda vengono processati sulla base del "first come – first served", cioè secondo l'ordine per cui il primo arrivato sarà il primo ad essere servito (FIFO).
39
+
Quando il motoere del browser avrà terminato con lo `script`, gestirà l'evento `mousemove`, quindi si occuperà del gestore del `setTimeout` (la callback), e via dicendo.
40
40
41
41
Fino a qui abbastanza semplice, giusto?
42
42
43
43
Ancora due dettagli:
44
44
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.
45
-
2. Se un task impiega troppo tempo, il browsere non puiò eseguire altri taskm, processare 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 con l'intera pagina. Questo succede in concomitanza di una serie di calcoli complessi, o degli errori di programmazione che portano ad un loop infinito.
45
+
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.
46
46
47
-
Questa era la teoria. Adesso vediamo come applicare questi concetti.
47
+
Questa era la teoria, ma vediamo come applicare questi concetti.
48
48
49
49
## Caso d'uso 1: Spezzettamento di task affamati di CPU (processi intensivi)
50
50
@@ -55,11 +55,11 @@ Per evidenziare il codice, compie delle analisi, crea molti elementi colorati, e
55
55
56
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.
57
57
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.
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.
59
59
60
-
Per dimostrare questo tipo di approccio, per amore della semplicità, invece di evidenziare una sintassi, prendiamo una funzione che conti i numeri da `1` a `1000000000`
60
+
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`
61
61
62
-
Se esegui il codice sotto, il motore si inchioderà per qualche istante. Per il JS server-side (lato server) questo è chiaramente visibile, e se lo stai eseguendo nella finestra del browser, prova a cliccare gli altri pulsanti -- potrei 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 conto non sarà terminato.
63
63
64
64
```js run
65
65
let i =0;
@@ -80,8 +80,7 @@ count();
80
80
Il browser potrebbe anche mostrare l'avviso "lo script sta impiegando troppo tempo" the script takes too long".
81
81
82
82
83
-
84
-
Ora, dividiamo l'operazione usando un `setTimeout` annidato:
83
+
Ora, dividiamo l'operazione con l'ausilio di un `setTimeout` annidato:
85
84
86
85
```js run
87
86
let i =0;
@@ -302,10 +301,10 @@ L'immagine più esausitva di un event loop è questa:
302
301
303
302
Il più dettagliato algoritmo dell'event loop (sebbene ancora semplicistico rispetto alla [specification](https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model)):
304
303
305
-
1. Rimuovi dalla coda ed esegui, il più vecchio task dalla coda dei *macrotask* (ad esempio "script").
306
-
2.Eseguit tutti i *microtasks*:
304
+
1. Rimuovi dalla coda ed esegui il task meno recente dalla coda dei *macrotask* (ad esempio "script").
305
+
2.Esegui tutti i *microtasks*:
307
306
- Se la cosa dei microtask non è vuota:
308
-
- Rimuovi dalla coda ed esegui il più vecchio dei microtask.
307
+
- Rimuovi dalla coda ed esegui il meno recente dei microtask.
309
308
3. Renderizza le modifiche se ve ne sono.
310
309
4. Se la coda dei macrotask è vuota, vai in sleep fino al prossimo macrotask.
0 commit comments