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: 1-js/12-generators-iterators/2-async-iterators-generators/article.md
+65-61Lines changed: 65 additions & 61 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,36 +1,35 @@
1
+
# Iteratori e generatori asincroni
1
2
2
-
# Async iterators and generators
3
+
Gli iteratori asincroni consentono di iterare su dati che arrivano in modo asincrono, a richiesta. Per esempio, quando eseguiamo una serie di download parziali dalla rete. I generatori asincroni ci consentono di semplificare questo processo.
3
4
4
-
Asynchronous iterators allow to iterate over data that comes asynchronously, on-demand. For instance, when we download something chunk-by-chunk over a network. Asynchronous generators make it even more convenient.
5
+
Vediamo prima un semplice esempio per prendere confidenza con la sintassi, dopodiché analizzeremo un caso d'uso reale.
5
6
6
-
Let's see a simple example first, to grasp the syntax, and then review a real-life use case.
7
+
## Iteratori asincroni
7
8
8
-
## Async iterators
9
+
Gli iteratori asincroni sono simili ai comuni iteratori, con alcune differenze sintattiche.
9
10
10
-
Asynchronous iterators are similar to regular iterators, with a few syntactic differences.
11
-
12
-
"Regular" iterable object, as described in the chapter <info:iterable>, look like this:
11
+
Gli oggetti iteratori "comuni", come abbiamo detto nel capitolo <info:iterable>, si presentano in questo modo:
13
12
14
13
```js run
15
14
let range = {
16
15
from:1,
17
16
to:5,
18
17
19
-
// for..of calls this method once in the very beginning
18
+
// for..of invoca questo metodo una sola volta all'inizio dell'esecuzione
20
19
*!*
21
20
[Symbol.iterator]() {
22
21
*/!*
23
-
// ...it returns the iterator object:
24
-
//onward, for await..of works only with that object,
25
-
//asking it for next values using next()
22
+
// ...ritorna l'oggetto iteratore:
23
+
//dopodiché, for..of interagisce solo con questo oggetto,
24
+
//chiedendogli i valori successivi tramite il metodo next()
26
25
return {
27
26
current:this.from,
28
27
last:this.to,
29
28
30
-
// next() is called on each iteration by the for..of loop
29
+
// next() viene invocato ad ogni iterazione dal ciclo for..of
31
30
*!*
32
31
next() { // (2)
33
-
//it should return the value as an object {done:.., value :...}
32
+
//dovrebbe ritornare il valore come un oggetto {done:.., value:..}
34
33
*/!*
35
34
if (this.current<=this.last) {
36
35
return { done:false, value:this.current++ };
@@ -43,43 +42,44 @@ let range = {
43
42
};
44
43
45
44
for(let value of range) {
46
-
alert(value); // 1 then 2, then 3, then 4, then 5
45
+
alert(value); // 1 poi 2, poi 3, poi 4, poi 5
47
46
}
48
47
```
49
48
50
-
If necessary, please refer to the [chapter about iterables](info:iterable) for details about regular iterators.
49
+
Se necessario, rileggersi il [capitolo sugli iteratori](info:iterable) per avere maggiori dettagli circa gli iteratori comuni.
50
+
51
+
Per rendere l'oggetto iteratore asincrono:
51
52
52
-
To make the object iterable asynchronously:
53
-
1. We need to use `Symbol.asyncIterator` instead of `Symbol.iterator`.
54
-
2.`next()` should return a promise.
55
-
3. To iterate over such an object, we should use `for await (let item of iterable)` loop.
As we can see, the structure is similar to regular iterators:
106
+
Possiamo notare che la struttura è simile a quella dei comuni iteratori:
107
107
108
-
1. To make an object asynchronously iterable, it must have a method `Symbol.asyncIterator``(1)`.
109
-
2. This method must return the object with `next()` method returning a promise `(2)`.
110
-
3. The `next()` method doesn't have to be `async`, it may be a regular method returning a promise, but `async` allows to use `await`, so that's convenient. Here we just delay for a second `(3)`.
111
-
4. To iterate, we use `for await(let value of range)``(4)`, namely add "await" after "for". It calls `range[Symbol.asyncIterator]()` once, and then its `next()` for values.
108
+
1. Per rendere un oggetto iterabile in modo asincrono, esso deve contenere un metodo `Symbol.asyncIterator``(1)`.
109
+
2. Questo metodo deve ritornare un oggetto contenente il metodo `next()`, che ritorna a sua volta una promise `(2)`.
110
+
3. Il metodo `next()` non deve necessariamente essere `async`; può essere un metodo normale che ritorna una promise, anche se `async` ci
111
+
consentirebbe di utilizzare `await`, che può tornarci utile. Nell'esempio, abbiamo utilizzato un ritardo di un secondo `(3)`.
112
+
4. Per iterare dobbiamo utilizzare il ciclo `for await(let value of range)``(4)`, si tratta di aggiungere "await" dopo il "for". Questo ciclo invoca il metodo `range[Symbol.asyncIterator]()` una sola volta, dopodiché il metodo invocherà`next()` per ottenere i valori.
112
113
113
-
Here's a small cheatsheet:
114
+
Ecco una semplice tabella di riepilogo:
114
115
115
-
|| Iterators | Async iterators|
116
-
|-------|-----------|-----------------|
117
-
|Object method to provide iterator|`Symbol.iterator`|`Symbol.asyncIterator`|
|Metodo dell'oggetto che restituisce l'iteratore|`Symbol.iterator`|`Symbol.asyncIterator`|
119
+
|Il valore ritornato da `next()`è| qualsiasi valore |`Promise`|
120
+
|ciclo da utilizzare|`for..of`|`for await..of`|
120
121
122
+
````warn header="Lo spread operator `...` non funziona in modo asincrono"
123
+
Le funzionalità offerte dai comuni iteratori (sincroni) non sono disponibili per gli iteratori asincroni.
121
124
122
-
````warn header="The spread operator `...` doesn't work asynchronously"
123
-
Features that require regular, synchronous iterators, don't work with asynchronous ones.
125
+
Per esempio, lo spread operator non puà essere utilizzato:
124
126
125
-
For instance, a spread operator won't work:
126
127
```js
127
-
alert([...range]); //Error, no Symbol.iterator
128
+
alert([...range]); //Errore, non c'à Symbol.iterator
128
129
```
129
130
130
-
That's natural, as it expects to find `Symbol.iterator`, same as `for..of` without `await`. Not `Symbol.asyncIterator`.
131
+
Questo è prevedibile, dal momento che lo spread operator ha bisogno di `Symbol.iterator` anziché`Symbol.asyncIterator`. Lo stesso vale per `for..of` (senza `await`).
132
+
131
133
````
132
134
133
-
## Async generators
135
+
## Generatori asincroni
134
136
135
-
As we already know, JavaScript also supports generators, and they are iterable.
137
+
Come già sappiamo, JavaScript supporta anche i cosiddetti generatori, che sono anche iteratori.
136
138
137
-
Let's recall a sequence generator from the chapter [](info:generators). It generates a sequence of values from `start` to `end`:
139
+
Ricordiamo l'esempio del generatore di una sequenza di numeri da `start` a `end`, nel capitolo [](info:generators):
alert(value); // 1, then 2, then 3, then 4, then 5
149
+
alert(value); // 1, poi 2, poi 3, poi 4, poi 5
148
150
}
149
151
```
150
152
151
-
In regular generators we can't use `await`. All values must come synchronously: there's no place for delay in `for..of`, it's a synchronous construct.
153
+
Nei normali generatori non possiamo usare `await`. Tutti i valori devono essere ritornati in modo sincrono: non c'è modo di ritornare valori "futuri" utilizzando il ciclo `for..of`, dal momento che si tratta di un costrutto di tipo sincrono.
152
154
153
-
But what if we need to use `await` in the generator body? To perform network requests, for instance.
155
+
Cosa fare se avessimo bisogno di usare `await` all'interno di un generatore? Per eseguire, ad esempio, una richiesta dalla rete?
154
156
155
-
No problem, just prepend it with `async`, like this:
157
+
Non c'è problema, sarà sufficiente anteporre la parola chiave `async`, come nell'esempio seguente:
@@ -173,41 +175,42 @@ No problem, just prepend it with `async`, like this:
173
175
174
176
let generator = generateSequence(1, 5);
175
177
for *!*await*/!* (let value of generator) {
176
-
alert(value); // 1, then 2, then 3, then 4, then 5
178
+
alert(value); // 1, poi 2, poi 3, poi 4, poi 5
177
179
}
178
180
179
181
})();
180
182
```
181
183
182
-
Now we have the async generator, iterable with `for await...of`.
184
+
In questo modo abbiamo ottenuto il generatore asincrono, che possiamo usare nelle iterazioni con il ciclo `for await..of`.
183
185
184
-
It's indeed very simple. We add the `async` keyword, and the generator now can use `await` inside of it, rely on promises and other async functions.
186
+
E' molto semplice. Aggiungiamo la parola chiave `async` ed ecco che il generatore può utilizzare `await` al suo interno e trarre vantaggio delle promise, così come di tutte le altre funzioni asincrone.
185
187
186
-
Technically, another the difference of an async generator is that its `generator.next()` method is now asynchronous also, it returns promises.
188
+
Tecnicamente, un'altra importante caratteristica dei generatori asincroni è che anche il relativo metodo `generator.next()` diventa asincrono, ritornando delle promise.
187
189
188
-
In a regular generator we'd use `result = generator.next()` to get values. In an async generator, we should add `await`, like this:
190
+
Con un generatore normale utilizzeremmo `result = generator.next()` per ottenere i valori ritornati. Con i generatori asincroni dobbiamo, invece, aggiungere `await`, come nell'esempio:
189
191
190
192
```js
191
193
result = await generator.next(); // result = {value: ..., done: true/false}
192
194
```
193
195
194
-
## Async iterables
196
+
## Iteratori asincroni
195
197
196
-
As we already know, to make an object iterable, we should add `Symbol.iterator` to it.
198
+
Come già sappiamo, per rendere un semplice oggetto un oggetto iteratore, dobbiamo aggiungere il metodo `Symbol.iterator`:
197
199
198
200
```js
199
201
let range = {
200
202
from: 1,
201
203
to: 5,
202
204
*!*
203
205
[Symbol.iterator]() {
204
-
return <object with next to make range iterable>
206
+
return <oggetto che abbia un metodo next() per trasformare l'oggetto in un iteratore>
205
207
}
206
208
*/!*
207
209
}
208
210
```
209
211
210
212
A common practice for `Symbol.iterator` is to return a generator, rather than a plain object with `next` as in the example before.
213
+
Un approccio comune è quello di far ritornare a `Symbol.iterator` un generatore anziché un normale oggetto con il metodo `next`, come nell'esempio precedente.
211
214
212
215
Let's recall an example from the chapter [](info:generators):
213
216
@@ -242,7 +245,7 @@ let range = {
242
245
*/!*
243
246
for(let value = this.from; value <= this.to; value++) {
244
247
245
-
// make a pause between values, wait for something
248
+
// make a pause between values, wait for something
246
249
await new Promise(resolve => setTimeout(resolve, 1000));
247
250
248
251
yield value;
@@ -361,4 +364,5 @@ In web-development we often meet streams of data, when it flows chunk-by-chunk.
361
364
362
365
We can use async generators to process such data, but it's also worth to mention that there's also another API called Streams, that provides special interfaces to work with such streams, to transform the data and to pass it from one stream to another (e.g. download from one place and immediately send elsewhere).
363
366
364
-
Streams API is not a part of JavaScript language standard.
367
+
Streams API is not a part of JavaScript language standard.
0 commit comments