À medida que o construto assíncrono / espera cresce em popularidade, cresce também o interesse em seus mecanismos internos. Tendo vasculhado a Internet, é fácil descobrir que o assíncrono / espera é baseado em promessas conhecidas e geradores, que são muito menos conhecidos e populares.

O material, cuja tradução publicamos hoje, é dedicado aos geradores. Nomeadamente, aqui falaremos sobre como eles funcionam e como eles, juntamente com as promessas, são usados nas entranhas da construção assíncrona / aguardada. O autor deste artigo diz que os geradores, para fins de aplicação prática, não são necessários para dominar. Além disso, ele observa que espera que o leitor seja um pouco versado em promessas.
Iteradores e Geradores
Em JavaScript, começando com o lançamento do padrão ES6, surgiram vários novos recursos que visam simplificar o trabalho com fluxos e coleções de dados assíncronos.
Iteradores e geradores se enquadram nessa categoria.
Um recurso notável dos iteradores é que eles fornecem um meio de acessar itens de coleção um de cada vez, permitindo rastrear o identificador do item atual.
function makeIterator(array) { var nextIndex = 0; console.log("nextIndex =>", nextIndex); return { next: function() { return nextIndex < array.length ? { value: array[nextIndex++], done: false } : { done: true }; } }; } var it = makeIterator(["simple", "iterator"]); console.log(it.next()); // {value: 'simple, done: false} console.log(it.next()); // {value: 'iterator, done: false} console.log(it.next()); // {done: true}
Acima, passamos à função
makeIterator()
uma pequena matriz contendo alguns elementos, após os quais passamos por ela com um iterador, chamando o método
it.next()
. Preste atenção nos comentários que demonstram os resultados obtidos usando o iterador.
Agora vamos falar sobre geradores. Geradores são funções que funcionam como fábricas de iteradores. Considere um exemplo simples e depois fale sobre dois mecanismos relacionados aos geradores.
function* sample() { yield "simple"; yield "generator"; } var it = sample(); console.log(it.next()); // {value: 'simple, done: false} console.log(it.next()); // {value: 'generator, done: false} console.log(it.next()); // {value: undefined, done: true}
Observe o asterisco na declaração da função. Isso indica que esta função é um gerador. Além disso, dê uma olhada na palavra-chave
yield
. Interrompe a execução da função e retorna um determinado valor. Na verdade, esses dois recursos são os dois mecanismos mencionados acima:
- Uma função geradora é uma função declarada usando um asterisco ao lado da palavra-chave da
function
ou ao lado do nome da função. - O iterador do gerador é criado quando a função do gerador é chamada.
Em geral, o exemplo acima demonstra a operação de uma função de fábrica que gera iteradores.
Agora que descobrimos o básico, vamos falar de coisas mais interessantes. Iteradores e geradores podem trocar dados em duas direções. Ou seja, os geradores, usando a palavra-chave
yield
, podem retornar valores aos iteradores, no entanto, os iteradores também podem enviar dados aos geradores usando o método
iterator.next('someValue')
. Aqui está como fica.
function* favBeer() { const reply = yield "What is your favorite type of beer?"; console.log(reply); if (reply !== "ipa") return "No soup for you!"; return "OK, soup."; } { const it = favBeer(); const q = it.next().value; // console.log(q); const a = it.next("lager").value; // console.log(a); } // What is your favorite beer? // lager // No soup for you! { const it = favBeer(); const q = it.next().value; // console.log(q); const a = it.next("ipa").value; // console.log(a); } // What is your favorite been? // ipa // OK, soup.
Geradores e Promessas
Agora podemos falar sobre como geradores e promessas formam a base da construção assíncrona / aguardada. Imagine que, em vez de retornar alguns valores usando a palavra-chave
yield
, o gerador retorne promessas. Nessa situação, o gerador pode ser envolvido em uma função que aguardará a promessa resolver e retornar o valor da promessa ao gerador no método
.next()
, conforme mostrado no exemplo anterior. Existe uma biblioteca popular,
co , que executa exatamente essas ações. É assim:
co(function* doStuff(){ var result - yield someAsyncMethod(); var another = yield anotherAsyncFunction(); });
Sumário
Segundo o autor deste material, os desenvolvedores de JS precisam saber como os geradores funcionam, apenas para entender os recursos da estrutura interna do design assíncrono / aguardado. Mas usá-los diretamente em seu próprio código não vale a pena. Os geradores introduzem no JavaScript a capacidade de pausar a função e retornar a ela quando (e se) o desenvolvedor considerar necessário. Até o momento, enquanto trabalhava com funções JS, esperávamos que elas, quando chamadas, fossem simplesmente executadas do começo ao fim. A capacidade de pausá-los já é algo novo, mas essa funcionalidade é convenientemente implementada na construção assíncrona / aguardada.
Certamente, pode-se argumentar com essa opinião. Por exemplo, um dos argumentos a favor dos geradores é que saber como eles funcionam é útil para depurar código com async / waitit, pois os geradores ficam ocultos nessa construção. No entanto, o autor do material acredita que isso é, no entanto, algo diferente do uso de geradores no código nativo.
Caros leitores! O que você acha dos geradores? Talvez você conheça algumas opções de uso que justifiquem sua aplicação direta no código dos projetos JS?
Código promocional real para um desconto de 10% em nossos servidores virtuais:
