2.1 Sintassi dei generatori
I generatori in JavaScript sono funzioni speciali che ti consentono di gestire l'esecuzione del codice. Possono sospendere la loro esecuzione e riprenderla più tardi, rendendoli uno strumento potente per lavorare con codice asincrono, iteratori e altre attività complesse.
I generatori si definiscono usando la funzione function* (nota l'asterisco). All'interno di un generatore si usa l'operatore yield per sospendere l'esecuzione e restituire un valore.
Dichiarazione di un generatore:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
Creazione dell'oggetto generatore
Chiamare un generatore non esegue immediatamente il suo corpo. Invece, restituisce un oggetto generatore, che può essere usato per iterare sui valori:
const gen = generatorFunction();
2.2 Uso dei generatori
Metodo next()
Il metodo next() si usa per riprendere l'esecuzione del generatore fino al prossimo operatore yield. Restituisce un oggetto con due proprietà:
value: il valore passato dall'operatoreyielddone: un valore booleano che indica se il generatore è completo (true) o no (false)
Esempio di utilizzo del metodo next():
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Iterazione su un generatore
I generatori possono essere usati con il ciclo for...of per iterare sui valori.
Esempio di iterazione su un generatore:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
for (const value of gen) {
console.log(value);
}
// Mostrerà: 1
// Mostrerà: 2
// Mostrerà: 3
Esempio di ritorno di valori
I generatori possono restituire un valore usando l'operatore return:
function* generatorFunction() {
yield 1;
yield 2;
return 3;
yield 4; // Questo yield non verrà mai eseguito
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
console.log(gen.next()); // { value: undefined, done: true }
2.3 Uso avanzato dei generatori
Interazione con un generatore
Il metodo next() può accettare un argomento, che viene passato al generatore e può essere utilizzato all'interno di esso.
Esempio di passaggio di valori a un generatore:
function* generatorFunction() {
const value1 = yield 1;
const value2 = yield value1 + 2;
yield value2 + 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next(10)); // { value: 12, done: false }
console.log(gen.next(20)); // { value: 23, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Gestione degli errori
I generatori consentono di gestire gli errori con il blocco try...catch.
Esempio di gestione degli errori:
function* generatorFunction() {
try {
yield 1;
yield 2;
} catch (error) {
console.log('Errore catturato:', error);
}
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.throw(new Error('Qualcosa è andato storto'))); // Errore catturato: Error: Qualcosa è andato storto
// { value: undefined, done: true }
Esempio di generatore per creare una sequenza infinita
I generatori possono essere usati per creare sequenze infinite di valori:
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
const gen = infiniteSequence();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// e così via
2.4 Esempi di uso pratico
Esempio 1: Generatore per iterare su un oggetto
function* objectEntries(obj) {
const keys = Object.keys(obj);
for (const key of keys) {
yield [key, obj[key]];
}
}
const obj = { a: 1, b: 2, c: 3 };
const gen = objectEntries(obj);
for (const [key, value] of gen) {
console.log(`${key}: ${value}`);
}
// Mostrerà:
// a: 1
// b: 2
// c: 3
Esempio 2: Generatore per implementare un semplice iteratore
const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (const value of myIterable) {
console.log(value);
}
// Mostrerà: 1
// Mostrerà: 2
// Mostrerà: 3
I generatori in JavaScript sono uno strumento potente per gestire l'esecuzione del codice, creare iteratori e lavorare con operazioni asincrone. Comprendere la sintassi e l'uso dei generatori aiuta a creare un codice più flessibile e leggibile, soprattutto quando si lavora con sequenze di dati e attività asincrone.
GO TO FULL VERSION