Gerando resultados sem esperar: um guia para iniciantes sobre Generators, Iterators e Async Iterators
Published: 2023-01-06 13:38:48

Quando trabalhamos com programação, muitas vezes precisamos tratar grandes quantidades de dados. Isso pode levar muito tempo, especialmente se estivermos trabalhando com grandes conjuntos de dados ou realizando operações complexas. Neste caso, é importante encontrar maneiras de otimizar o processo para que possamos tratar esses dados de maneira mais eficiente. É aí que entram os Generators, Iterators e Async Iterators.

## O que são Generators, Iterators e Async Iterators?
Generators, Iterators e Async Iterators são ferramentas que nos permitem tratar grandes quantidades de dados de maneira mais eficiente. Eles funcionam dividindo o processo em etapas, permitindo que o programa execute uma etapa de cada vez, em vez de precisar processar todos os dados de uma só vez.

Para entender como eles funcionam, vamos usar a analogia de uma receita de bolo. Imagine que você está fazendo um bolo e precisa seguir uma receita que contém muitos ingredientes e passos. Usando um Generator ou Iterator, seria como se você pudesse preparar um ingrediente de cada vez, em vez de precisar misturar todos os ingredientes de uma só vez. Isso significa que você pode ir preparando cada etapa da receita à medida que ela é necessária, em vez de precisar esperar até que todos os ingredientes estejam prontos.

O Async Iterator funciona de maneira semelhante, mas é especialmente útil quando estamos trabalhando com operações assíncronas, ou seja, operações que não precisam ser concluídas para que o programa possa continuar a executar outras tarefas. Usando a mesma analogia da receita de bolo, o Async Iterator seria como se você pudesse preparar um ingrediente enquanto o forno está aquecendo, em vez de precisar esperar até que o forno esteja pronto para começar a preparar os ingredientes.

## Para que servem Generators, Iterators e Async Iterators?
Generators, Iterators e Async Iterators são muito úteis quando precisamos tratar grandes quantidades de dados de maneira mais eficiente. Eles nos permitem dividir o processo em etapas, o que significa que podemos processar os dados de maneira mais eficiente e evitar sobrecarregar a memória do computador.
Além disso, Generators, Iterators e Async Iterators são especialmente úteis quando estamos trabalhando com grandes conjuntos de dados ou realizando operações complexas, pois nos permitem tratar os dados de maneira mais eficiente. Por exemplo, se você estiver trabalhando com uma lista de milhões de números e precisar calcular a média de todos eles, pode usar um Generator para calcular a média de cada grupo de números de cada vez, em vez de precisar calcular a média de todos os números de uma só vez.

## Benefícios de usar Generators, Iterators e Async Iterators:
Além de permitir que tratemos grandes quantidades de dados de maneira mais eficiente, há outros benefícios em usar Generators, Iterators e Async Iterators:

- **Economia de memória**: Como os Generators, Iterators e Async Iterators dividem o processo em etapas, eles nos permitem tratar os dados de maneira mais eficiente, evitando sobrecarregar a memória do computador.

- **Leitura mais fácil do código**: Usar Generators, Iterators e Async Iterators pode tornar o código mais legível, pois eles nos permitem dividir o processo em etapas mais fáceis de entender.

- **Execução mais rápida**: Como os Generators, Iterators e Async Iterators nos permitem tratar os dados de maneira mais eficiente, eles também podem tornar o processo mais rápido.

## Quando usar Generators, Iterators e Async Iterators:
Generators, Iterators e Async Iterators são úteis em qualquer situação em que precisamos tratar grandes quantidades de dados de maneira mais eficiente. Alguns exemplos comuns incluem:

- Quando precisamos processar grandes conjuntos de dados, como uma lista de milhões de números.
- Quando precisamos realizar operações complexas, como calcular a média de uma grande lista de números.
- Quando estamos trabalhando com operações assíncronas, como fazer solicitações HTTP em um loop.

## Como usar Generators, Iterators e Async Iterators:
Para usar Generators, Iterators e Async Iterators em seu código, basta seguir os seguintes passos:

- Como usar Generators em JavaScript:

Crie uma função que retorne os dados de um em um. Para criar um Generator, basta usar a palavra-chave "yield" em vez de "return".

```
function* meuGenerator(lista) {
  for (const item of lista) {
    yield item;
  }
}

// Usando o Generator
for (const item of meuGenerator([1, 2, 3])) {
  console.log(item);
}

```

- Como usar Iterators em JavaScript:

Para criar um Iterator em JavaScript, basta criar um objeto que implemente o método "next". Esse método deve retornar um objeto com as propriedades "value" e "done". A propriedade "value" deve conter o próximo item do Iterator, enquanto a propriedade "done" deve ser "true" quando não houver mais itens para retornar.
Exemplo:

```
const meuIterator = {
  lista: [1, 2, 3],
  indice: 0,
  next() {
    if (this.indice >= this.lista.length) {
      return { done: true };
    }
    const item = this.lista[this.indice];
    this.indice += 1;
    return { value: item, done: false };
  },
};

// Usando o Iterator
for (const item of meuIterator) {
  console.log(item);
}

```
- Como usar Async Iterators em JavaScript:

Para criar um Async Iterator em JavaScript, basta criar um objeto que implemente o método "next". Esse método deve retornar um objeto com as propriedades "value" e "done". A propriedade "value" deve conter o próximo item do Async Iterator, enquanto a propriedade "done" deve ser "true" quando não houver mais itens para retornar. Além disso, o método "next" deve ser assíncrono, ou seja, deve ser precedido pela palavra-chave "async".

Exemplo:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ay1mtui6g2fisgy9x53h.png)

Neste código, estamos criando um Async Iterator chamado "meuAsyncIterator". Ele possui uma propriedade "lista" com os valores [1, 2, 3] e uma propriedade "indice" com o valor 0.

O Async Iterator também possui um método "next" que é assíncrono. Quando esse método é chamado, ele verifica se o índice atual é maior ou igual à quantidade de itens na lista. Se for, retorna um objeto com a propriedade "done" com o valor "true", indicando que não há mais itens para retornar. Se o índice ainda não tiver alcançado o final da lista, ele pega o item na posição atual da lista, incrementa o índice em 1 e retorna um objeto com as propriedades "value" (com o item atual) e "done" (com o valor "false").

Em seguida, estamos usando o Async Iterator dentro de uma função assíncrona anônima. Essa função é imediatamente invocada com o uso dos parênteses no final. Dentro da função, usamos o loop "for await" para iterar sobre o Async Iterator. A cada iteração, o método "next" do Async Iterator é chamado e o item retornado é atribuído à variável "item". Em seguida, imprimimos o valor de "item" no console. Quando o método "next" retorna um objeto com a propriedade "done" com o valor "true", o loop é finalizado.


Neste guia, aprendemos o que são Generators, Iterators e Async Iterators e como usá-los em JavaScript. Essas são ferramentas muito úteis quando precisamos tratar grandes quantidades de dados de maneira mais eficiente, permitindo que dividamos o processo em etapas e evitemos sobrecarregar a memória do computador.

Agora que você sabe como usar Generators, Iterators e Async Iterators em seu código, aqui estão alguns próximos passos que você pode seguir:

Experimente usar Generators, Iterators e Async Iterators em seus próprios projetos.
Aprenda mais sobre os detalhes da sintaxe e uso de Generators, Iterators e Async Iterators em JavaScript. A documentação do MDN é um ótimo lugar para começar:
Generators: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators
Iterators: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterators
Async Iterators: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Async_Iterators
Obrigado pela sua atenção! Espero que este guia tenha sido útil para você.