O que são geradores em Dart (sync* e async*) e como eles funcionam?
sobes.tech IA
Resposta da IA
Os geradores em Dart são funções que devolvem uma sequência de valores à medida que são gerados, em vez de todo o resultado de uma vez. Utilizam as palavras-chave sync* para geradores síncronos e async* para geradores assíncronos.
Geradores síncronos (sync*)
Devolvem um objeto do tipo Iterable. Utilizam a palavra-chave yield para emitir o próximo valor. O fluxo de execução é pausado até que o próximo valor seja solicitado (por exemplo, num ciclo for-in).
Iterable<int> countUpTo(int max) sync* {
for (int i = 1; i <= max; i++) {
yield i; // Emite o valor
}
}
Geradores assíncronos (async*)
Devolvem um objeto do tipo Stream. Utilizam a palavra-chave yield para emitir o próximo valor. Também usam yield* para emitir todos os valores de outro Stream. O fluxo de execução é pausado e retomado quando há um novo evento assíncrono.
Stream<int> countUpToAsync(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(milliseconds: 100)); // Simulação de trabalho assíncrono
yield i; // Emite o valor
}
}
Como funcionam:
Ao chamar a função geradora, o corpo da função não é executado imediatamente. É devolvido um objeto (seja Iterable ou Stream). A execução real do corpo começa apenas quando se tenta obter o valor pela primeira vez do objeto devolvido. Quando se atinge a palavra-chave yield, o valor é passado "para fora" e o estado da função é guardado. A execução do corpo é pausada. Quando se tenta obter o próximo valor, a execução retoma de onde parou, até ao próximo yield ou ao fim da função.
Diferenças:
| Característica | sync* (Síncrono) | async* (Assíncrono) |
|---|---|---|
| Tipo devolvido | Iterable |
Stream |
| Palavras-chave | sync*, yield |
async*, yield, yield* |
Uso de await |
Não permitido | Permitido |
| Pausa | Até ao pedido do próximo valor | Até à próxima ocorrência de um valor assíncrono |