Atualizado: 07/12/2024

Geradores Assíncronos - JavaScript

Os iteradores assíncronos nos permitem criar geradores assíncronos. Eles possibilitam o uso do operador await para receber e retornar dados de forma assíncrona.

Para criar um gerador assíncrono, basta adicionar o operador async antes da função geradora:

async function* nomeDaFuncaoGeradora() {
    yield valorRetornado;
}

Vamos considerar um gerador simples:

async function* generatePersonAsync() {
    yield "Tom";
}

Aqui, definimos o gerador assíncrono generatePersonAsync, que retorna um valor, a string "Tom".

Uma característica dos geradores assíncronos é que, ao chamar seu método next(), ele retorna um objeto Promise. Esse Promise retorna um objeto com duas propriedades: { value, done }, onde value contém o valor retornado e done indica se ainda há dados disponíveis no gerador.

Por exemplo, considerando o gerador assíncrono definido acima:

async function* generatePersonAsync() {
    yield "Tom";
}
const personGenerator = generatePersonAsync();
personGenerator.next(); // Promise

Aqui, ao chamar o método next(), obtemos uma promise. Através do método then(), podemos extrair o objeto da promise:

const personGenerator = generatePersonAsync();
personGenerator.next()
    .then(data => console.log(data)); // {value: "Tom", done: false}
    

E ao acessar a propriedade value do objeto retornado pela promise, podemos obter os dados:

const personGenerator = generatePersonAsync();
personGenerator.next()
    .then(data => console.log(data.value)); // Tom

Podemos usar o operador await para obter os dados do método next() do gerador:

async function* generatePersonAsync() {
    yield "Tom";
    yield "Sam";
    yield "Bob";
}
async function printPeopleAsync() {
    const personGenerator = generatePersonAsync();
    while (!(person = await personGenerator.next()).done) {
        console.log(person.value);
    }
}
 
printPeopleAsync();

A saída no console será:

Tom
Sam
Bob

Como o gerador assíncrono é um iterador assíncrono, também podemos obter seus dados usando o loop for-await-of:

async function* generatePersonAsync() {
    yield "Tom";
    yield "Sam";
    yield "Bob";
}
async function printPeopleAsync() {
    const personGenerator = generatePersonAsync();
    for await (person of personGenerator) {
        console.log(person);
    }
}
 
printPeopleAsync();
// Tom
// Sam
// Bob

Uso do await em Geradores Assíncronos

A principal vantagem dos geradores assíncronos é a possibilidade de usar o operador await para obter dados de fontes que utilizam APIs assíncronas.

async function* generatePersonAsync(people) {
    for (const person of people)
        yield await new Promise(resolve => setTimeout(() => resolve(person), 2000));
}
async function printPeopleAsync(people) {
    for await (const item of generatePersonAsync(people)) {
        console.log(item); 
    }
}
printPeopleAsync(["Tom", "Sam", "Bob"]);

Aqui, para simular a obtenção de dados de uma fonte assíncrona, usamos uma promise que, após 2000 milissegundos, retorna um dos elementos do array passado para a função geradora:

yield await new Promise(resolve => setTimeout(() => resolve(person), 2000));
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com