Skip to content

Commit cdaf839

Browse files
Update article.md
1 parent 734ed1a commit cdaf839

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

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

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11

22
# Event loop: microtasks e macrotasks
33

4-
Il flusso di esecuzione di Javascript, cos&igrave come quello di Node.js, sono basati sull' *event loop*.
4+
Il flusso di esecuzione di Javascript, così come quello di Node.js, è basato sull' *event loop*.
55

6-
Comprendere come un event loop lavora è importante per le ottimizzazioni, ed a volte, anche per creare delle architetture migliori.
6+
Comprendere come funziona un event loop è importante sia per ottimizzazione, ma a volte, anche per creare delle architetture migliori.
77

8-
In questo capitolo affronteremo i dettagli teorici su come funziona, 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

@@ -20,46 +20,46 @@ Questa è una esposizione di quello che vediamo quando navighiamo una pagi
2020

2121
Esempio di tasks:
2222

23-
- Quando uno script esterno `<script src="...">` viene caricato (load), il task è quello di eseguirlo.
23+
- Quando uno script esterno `<script src="...">` viene caricato (load), il task &egrave; quello di eseguirlo.
2424
- Quando un utente sposta il puntatore del mouse, il task &egrave; quello di fare il dispatch dell'evento `mousemove` ed eseguirne eventuali handlers (gestori).
25-
- Quando è scaduto il tempo per `setTimeout` già schedulato, il task è quello di eseguirne la callback.
25+
- Quando &egrave; scaduto il tempo per `setTimeout` gi&agrave; schedulato, il task &egrave; quello di eseguirne la callback.
2626
- ...e cos&igrave; via.
2727

2828
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).
2929

30-
Però potrebbe succedere che mentre il motore è occupato, arrivi un task, in questo caso, questo viene messo in coda.
30+
Per&ograve; potrebbe succedere che mentre il motore &egrave; occupato, arrivi un task, in questo caso, questo viene messo in coda.
3131

3232
I task formano una coda, la cosiddetta "macrotask queue" (termine mutuato V8, il motore Javascript di Chrome e di Node.js):
3333

3434
![](eventLoop.svg)
3535

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 &egrave; occupato nell'esecuzione di uno `script`, l'utente muove il mouse generando un `mousemove`, e magari nello stesso istante &egrave; scaduto il tempo di un `setTimeout`, questi task formano una queue (una coda di esecuzione) come illustrato nella figura di sopra.
3737

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&agrave; del gestore del `setTimeout` (la callback), e cos&igrave;
38+
I task dalla coda vengono processati sulla base del "first come – first served", cio&egrave; secondo l'ordine che il primo arrivato sar&agrave; il primo ad essere servito (FIFO).
39+
Quando il motere del browser avr&agrave; terminato con lo `script`, gestir&agrave; l'evento `mousemove`, quindi si occuper&agrave; del gestore del `setTimeout` (la callback), e cos&igrave;
4040

4141
Fino a qui abbastanza semplice, giusto?
4242

4343
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.
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 browsere non pui&ograve; eseguire altri taskm, processare eventi utente, e cos&igrave; 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.
4646

4747
Questa era la teoria. Adesso vediamo come applicare questi concetti.
4848

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

5151
Poniamo il caso che abbiamo un task affamato di CPU.
5252

53-
Per esempio, la syntax-highlighting (usata per colorare ed evidenziare gli esempi del codice in questa pagina) è abbastanza pesante per la CPU.
54-
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.
53+
Per esempio, la syntax-highlighting (usata per colorare ed evidenziare gli esempi del codice in questa pagina) &egrave; abbastanza pesante per la CPU.
54+
Per evidenziare il codice, compie delle analisi, crea molti elementi colorati, e li aggiunge al documento -- un testo di grosse dimensioni pu&ograve; impiegare molto tempo.
5555

5656
Mentre il motore &egrave; occupato con l'evidenziatura, non pu&ograve; fare le altre cose relative al DOM, processare gli eventi dell'utente, etc. pu&ograve; persino causare "singhiozzamenti" al pc o addirittura "inchiodarlo", la qual cosa &egrave; 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.
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&igrave; via.
5959

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, per amore della semplicit&agrave;, invece di 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&agrave; 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&agrave; per qualche istante. Per il JS server-side (lato server) questo &egrave; chiaramente visibile, e se lo stai eseguendo nella finestra del browser, prova a cliccare gli altri pulsanti -- potrei notare che non verr&agrave; gestito nessun altro evento fino a quando il conto non sar&agrave; terminato.
6363

6464
```js run
6565
let i = 0;
@@ -113,7 +113,7 @@ Una singola esecuzione di `count` fa una parte dell'operazione `(*)`, e rischedu
113113

114114
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.
115115

116-
La cosa ragguardevole è 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.
116+
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.
117117

118118
Per renderli un po' pi&ugrave; facciamo un miglioramento.
119119

@@ -140,21 +140,21 @@ function count() {
140140
count();
141141
```
142142

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

145145
Se lo esegui, &egrave; facile notare che impiega meno tempo in modo significativo.
146146

147147

148148
Perch&egrave;?
149149

150-
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ù veloce sar&agrave; l'esecuzione.
150+
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.
151151
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.
152152

153153
## Caso d'uso 2: Indicazione dei progressi di una operazione
154154

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

157-
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 è terminato.
157+
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.
158158

159159
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?
160160

@@ -180,7 +180,7 @@ Qui c'&egrave; la demo, i cambiamenti a `i` non verrano mostrati fino a quando l
180180

181181
Se noi dividiamo il task pesante in pezzi usando `setTimeout`, allora tra essi, verranno mostrate le variazioni.
182182

183-
Questo sembra più carino:
183+
Questo sembra pi&ugrave; carino:
184184

185185
```html run
186186
<div id="progress"></div>
@@ -214,7 +214,7 @@ Adesso il `<div>` mostra via via, valori crescenti di `i`,come se fosse una sort
214214
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.
215215
Possiamo farlo, avvolgendo (wrapping) il codice all'interno dei `setTimeout` a ritardo zero.
216216

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 è 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; stto del tutto gestito.
218218

219219

220220
```js
@@ -255,11 +255,11 @@ alert("code");
255255

256256
Che sta succedendo all'ordine qui?
257257

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

262-
L'immagine pi&ugrave; esausitva di un event loop &egrave; è questa:
262+
L'immagine pi&ugrave; esausitva di un event loop &egrave; &egrave; questa:
263263

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

@@ -300,22 +300,22 @@ L'immagine pi&ugrave; esausitva di un event loop &egrave; questa:
300300

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

303-
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)):
303+
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)):
304304

305-
1. Rimuovi dalla coda ed esegui, il più vecchio task dalla coda dei *macrotask* (ad esempio "script").
305+
1. Rimuovi dalla coda ed esegui, il pi&ugrave; vecchio task dalla coda dei *macrotask* (ad esempio "script").
306306
2. Eseguit tutti i *microtasks*:
307-
- Se la cosa dei microtask non è vuota:
308-
- Rimuovi dalla coda ed esegui il più vecchio dei microtask.
307+
- Se la cosa dei microtask non &egrave; vuota:
308+
- Rimuovi dalla coda ed esegui il pi&ugrave; vecchio dei microtask.
309309
3. Renderizza le modifiche se ve ne sono.
310-
4. Se la coda dei macrotask è vuota, vai in sleep fino al prossimo macrotask.
310+
4. Se la coda dei macrotask &egrave; vuota, vai in sleep fino al prossimo macrotask.
311311
5. Vai al passo 1.
312312

313313
Per schedulare un nuovo *macrotask*:
314314
- Use zero delayed `setTimeout(f)`.
315315

316316
Questo potrebbe essere usato per divitere task di calcolopesante in pezzi, di modo che tra questi, il browser possa eseguire altre operazioni.
317317

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

320320
Per schedulare un nuovo *microtask*
321321
- Usa `queueMicrotask(f)`.
@@ -328,9 +328,9 @@ Quindi uno potrebbe volere che la coda `queueMicrotask` eseguisse una funzione i
328328
```smart header="Web Workers"
329329
Per lunghi calcoli pesanti che non possono bloccare l'event loop, possiamo usare i [Web Workers](https://html.spec.whatwg.org/multipage/workers.html).
330330
331-
Che è un modo per eseguire del codice in un altro thread parallelo.
331+
Che &egrave; un modo per eseguire del codice in un altro thread parallelo.
332332
333333
I Web Workers possono scambiarsi messaggi con il processo principale, ma hanno le loro variabili ed i loro event loop.
334334
335-
I Web Workers non hanno accesso al DOM, quindi sono adatti principalmente per i calcoli, per usare contemporaneamente più cores CPU.
335+
I Web Workers non hanno accesso al DOM, quindi sono adatti principalmente per i calcoli, per usare contemporaneamente pi&ugrave; cores CPU.
336336
```

0 commit comments

Comments
 (0)