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
+46-47Lines changed: 46 additions & 47 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -209,43 +209,42 @@ let range = {
209
209
}
210
210
```
211
211
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
212
Un approccio comune è quello di far ritornare a `Symbol.iterator` un generatore anziché un normale oggetto con il metodo `next`, come nell'esempio precedente.
214
213
215
-
Let's recall an example from the chapter [](info:generators):
214
+
Ricordiamo di seguito un esempio dal capitolo [](info:generators):
216
215
217
216
```js run
218
217
let range = {
219
218
from: 1,
220
219
to: 5,
221
220
222
-
*[Symbol.iterator]() { // a shorthand for [Symbol.iterator]: function*()
221
+
*[Symbol.iterator]() { // sintassi compatta di [Symbol.iterator]: function*()
223
222
for(let value = this.from; value <= this.to; value++) {
224
223
yield value;
225
224
}
226
225
}
227
226
};
228
227
229
228
for(let value of range) {
230
-
alert(value); // 1, then 2, then 3, then 4, then 5
229
+
alert(value); // 1, poi 2, poi 3, poi 4, poi 5
231
230
}
232
231
```
233
232
234
-
Here a custom object `range` is iterable, and the generator `*[Symbol.iterator]` implements the logic for listing values.
233
+
In questo esempio l'oggetto `range` è un iteratore e il generatore `*[Symbol.iterator]` implementa la logica per elencare i valori.
235
234
236
-
If we'd like to add async actions into the generator, then we should replace `Symbol.iterator` with async `Symbol.asyncIterator`:
235
+
Se volessimo aggiungere delle funzionalità asincrone al generatore, dovremmo sostituire `Symbol.iterator` con async `Symbol.asyncIterator`:
237
236
238
237
```js run
239
238
let range = {
240
239
from: 1,
241
240
to: 5,
242
241
243
242
*!*
244
-
async *[Symbol.asyncIterator]() { // same as [Symbol.asyncIterator]: async function*()
243
+
async *[Symbol.asyncIterator]() { // come per [Symbol.asyncIterator]: async function*()
245
244
*/!*
246
245
for(let value = this.from; value <= this.to; value++) {
247
246
248
-
// make a pause between values, wait for something
247
+
// mettiamo una pausa tra i volori ritornati, aspettando un secondo
249
248
await new Promise(resolve => setTimeout(resolve, 1000));
250
249
251
250
yield value;
@@ -256,70 +255,70 @@ let range = {
256
255
(async () => {
257
256
258
257
for *!*await*/!* (let value of range) {
259
-
alert(value); // 1, then 2, then 3, then 4, then 5
258
+
alert(value); // 1, poi 2, poi 3, poi 4, poi 5
260
259
}
261
260
262
261
})();
263
262
```
264
263
265
-
Now values come with a delay of 1 second between them.
264
+
Adesso i valori verranno ritornati con un ritardo di 1 secondo tra l'uno e l'altro.
266
265
267
-
## Real-life example
266
+
## Esempio reale
268
267
269
-
So far we've seen simple examples, to gain basic understanding. Now let's review a real-life use case.
268
+
Finora abbiamo visto esempi molto semplici, tanto per prendere confidenza. Vediamo ora un esempio di caso d'uso reale.
270
269
271
-
There are many online services that deliver paginated data. For instance, when we need a list of users, a request returns a pre-defined count (e.g. 100 users) - "one page", and provides an URL to the next page.
270
+
Ci sono molti servizi online che restituiscono dati paginati. Per esempio, quando abbiamo bisogno di una lista di utenti, una richiesta ritorna un numero predefinito di risultati (ad esempio 100 utenti) - "una pagina", e ci ritorna anche una URL per ottenere la pagina successiva.
272
271
273
-
The pattern is very common, it's not about users, but just about anything. For instance, GitHub allows to retrieve commits in the same, paginated fashion:
272
+
E' un modello molto comune, non solo per gli utenti, ma per qualsiasi cosa. Ad esempio, GitHub consente di ottenere la lista di commit allo stesso modo, tramite la paginazione:
274
273
275
-
- We should make a request to URL in the form `https://api.github.com/repos/<repo>/commits`.
276
-
- It responds with a JSON of 30 commits, and also provides a link to the next page in the `Link` header.
277
-
- Then we can use that link for the next request, to get more commits, and so on.
274
+
- Eseguiamo una richiesta alla URL nella forma `https://api.github.com/repos/<repo>/commits`.
275
+
- Il server risponde con un JSON di 30 commit e ci ritorna anche un link alla pagina successiva nell'header `Link`.
276
+
- Dopodiché possiamo usare tale link per la richiesta successiva, ottenendo le commit successive e così via.
278
277
279
-
But we'd like to have is a simpler API: an iterable object with commits, so that we could go over them like this:
278
+
Ci piacerebbe, tuttavia, avere una API più semplice: un oggetto iteratore per le commit, che ci consenta di elencarle nel seguente modo:
280
279
281
280
```js
282
-
let repo = 'javascript-tutorial/en.javascript.info'; // GitHub repository to get commits from
281
+
let repo = 'javascript-tutorial/en.javascript.info'; // repository GitHub dal quale ottenere le commit
283
282
284
283
for await (let commit of fetchCommits(repo)) {
285
284
// process commit
286
285
}
287
286
```
288
287
289
-
We'd like a call, like `fetchCommits(repo)` to get commits for us, making requests whenever needed. And let it care about all pagination stuff, for us it'll be a simple `for await..of`.
288
+
Ci piacerebbe un'invocazione, come ad esempio `fetchCommits(repo)` per ottenere le commit, che esegua richieste ogni volta che ne abbiamo bisogno e senza preoccuparci della logica di paginazione. Ad esempio, una soluzione semplice del tipo `for await..of`.
290
289
291
-
With async generators that's pretty easy to implement:
290
+
Grazie ai generatori asincroni diventa piuttosto semplice da implementare:
292
291
293
292
```js
294
293
async function* fetchCommits(repo) {
295
294
let url = `https://api.github.com/repos/${repo}/commits`;
headers: {'User-Agent': 'Our script'}, // github richiede un header user-agent
300
299
});
301
300
302
-
const body = await response.json(); // (2) response is JSON (array of commits)
301
+
const body = await response.json(); // (2) la risposta è un JSON (array di commit)
303
302
304
-
// (3) the URL of the next page is in the headers, extract it
303
+
// (3) la URL della pagina successiva è negli header, dunque dobbiamo estrarla
305
304
let nextPage = response.headers.get('Link').match(/<(.*?)>; rel="next"/);
306
305
nextPage = nextPage && nextPage[1];
307
306
308
307
url = nextPage;
309
308
310
-
for(let commit of body) { // (4) yield commits one by one, until the page ends
309
+
for(let commit of body) { // (4) restituisce (yield) le commit una ad una fino alla fine della pagina
311
310
yield commit;
312
311
}
313
312
}
314
313
}
315
314
```
316
315
317
-
1. We use the browser [fetch](info:fetch) method to download from a remote URL. It allows to supply authorization and other headers if needed, here GitHub requires `User-Agent`.
318
-
2. The fetch result is parsed as JSON, that's again a `fetch`-specific method.
319
-
3. We should get the next page URL from the `Link` header of the response. It has a special format, so we use a regexp for that. The next page URL may look like `https://api.github.com/repositories/93253246/commits?page=2`, it's generated by GitHub itself.
320
-
4. Then we yield all commits received, and when they finish -- the next `while(url)` iteration will trigger, making one more request.
316
+
1. Utilizziamo il metodo [fetch](info:fetch) del browser per ottenere i dati dalla URL remota. Questo ci consente di fornire al server le autorizzazioni e le intestazioni (header) richieste. Ad esempio GitHub richiede `User-Agent`:
317
+
2. Il risultato di fetch viene interpretato come un JSON, altra caratteristica del metodo `fetch`.
318
+
3. Dovremmo, quindi, ottenere la URL alla pagina successiva dal header `Link` della risposta. Siccome ha un formato particolare, utilizziamo un'espressione regolare. La URL della pagina successiva potrebbe essere simile a `https://api.github.com/repositories/93253246/commits?page=2` e viene generata dallo stesso GitHub.
319
+
4. Infine, ritorniamo tutte le commit ricevute tramite `yield` e, una volta terminate, la successiva iterazione `while(url)` verrà invocata, eseguendo un'ulteriore richiesta.
321
320
322
-
An example of use (shows commit authors in console):
321
+
Un esempio di utilizzo (visualizza gli autori delle commit nella console):
323
322
324
323
```js run
325
324
(async () => {
@@ -338,31 +337,31 @@ An example of use (shows commit authors in console):
338
337
})();
339
338
```
340
339
341
-
That's just what we wanted. The internal mechanics of paginated requests is invisible from the outside. For us it's just an async generator that returns commits.
340
+
Questo è esattamente quello che volevamo. I meccanismi interni delle richieste paginate sono invisibili dall'esterno. Per noi non è altro che un generatore asincrono che ritorna delle commit.
342
341
343
-
## Summary
342
+
## Sommario
344
343
345
-
Regular iterators and generators work fine with the data that doesn't take time to generate.
344
+
I normali iteratori e generatori funzionano bene con dati che non richiedono tempo per essere generati.
346
345
347
-
When we expect the data to come asynchronously, with delays, their async counterparts can be used, and `for await..of` instead of `for..of`.
346
+
Quando i dati ci arrivano in modo asincrono, con dei ritardi, possiamo usare iteratori e generatori asincroni, tramite il ciclo `for await..of` anziché `for..of`.
348
347
349
-
Syntax differences between async and regular iterators:
348
+
Differenze sintattiche tra iteratori sincroni e asincroni:
350
349
351
-
| | Iterators | Async iterators |
352
-
|-------|-----------|-----------------|
353
-
| Object method to provide iterator | `Symbol.iterator` | `Symbol.asyncIterator` |
354
-
| `next()` return value is | any value| `Promise` |
In web-development we often meet streams of data, when it flows chunk-by-chunk. For instance, downloading or uploading a big file.
362
+
Nello sviluppo web incontriamo spesso flussi di dati che vengono ritornati "in gruppi". Per esempio, il download o l'upload di file grandi.
364
363
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).
364
+
Possiamo usare i generatori asincroni per processare questo tipo di dati but vale anche la pena di menzionare che c'è un'altra API, chiamata Streams, che ci fornisce delle interfacce speciali per gestire questi flussi di dati, per trasformarli e passarli ad altri flussi per ulteriori manipolazioni (ad esempio scaricare dati da qualche sorgente e poi immediatamente inviarli da qualche parte).
366
365
367
-
Streams API is not a part of JavaScript language standard.
366
+
Le Streams API non fanno parte del linguaggio JavaScript standard.
0 commit comments