Cosa sono i generatori in Dart (sync* e async*) e come funzionano?
sobes.tech AI
Risposta dell'AI
I generatori in Dart sono funzioni che restituiscono una sequenza di valori man mano che vengono generati, anziché l'intero risultato subito. Si usano le parole chiave sync* per generatori sincroni e async* per generatori asincroni.
Generatori sincroni (sync*)
Restituiscono un oggetto di tipo Iterable. Usano la parola chiave yield per emettere il valore successivo. Il flusso di esecuzione si mette in pausa fino a quando non viene richiesto il valore successivo (ad esempio, in un ciclo for-in).
Iterable<int> countUpTo(int max) sync* {
for (int i = 1; i <= max; i++) {
yield i; // Emette il valore
}
}
Generatori asincroni (async*)
Restituiscono un oggetto di tipo Stream. Usano la parola chiave yield per emettere il valore successivo. Usano anche yield* per emettere tutti i valori di un altro Stream. Il flusso di esecuzione si mette in pausa e si riprende quando si verifica un nuovo evento asincrono.
Stream<int> countUpToAsync(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(milliseconds: 100)); // Simulazione di lavoro asincrono
yield i; // Emette il valore
}
}
Come funzionano:
Quando si chiama la funzione generatrice, il corpo della funzione non viene eseguito immediatamente. Viene restituito un oggetto (sia Iterable che Stream). L'esecuzione reale del corpo inizia solo quando si tenta di ottenere il valore per la prima volta dall'oggetto restituito. Quando si raggiunge la parola chiave yield, il valore viene passato "all'esterno" e lo stato della funzione viene salvato. L'esecuzione del corpo viene messa in pausa. Quando si tenta di ottenere il prossimo valore, l'esecuzione riprende da dove si era interrotta, fino al prossimo yield o alla fine della funzione.
Differenze:
| Caratteristica | sync* (Sincrono) | async* (Asincrono) |
|---|---|---|
| Tipo restituito | Iterable |
Stream |
| Parole chiave | sync*, yield |
async*, yield, yield* |
Uso di await |
Non consentito | Consentito |
| Pausa | Fino alla richiesta del valore successivo | Fino all'arrivo del prossimo evento asincrono |