function*
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.
A declaração function*
(palavra chave function
seguida de um asterisco) define uma função geradora (generator function), que retorna um objeto Generator
.
Experimente
Você também pode definir funções geradoras usando o construtor GeneratorFunction
ou a sintaxe da expressão de uma função.
Sintaxe
function* name([param[, param[, ... param]]]) { statements }
name
-
O nome da função.
param
-
O nome do argumento que será passado á função. Uma função pode ter até 255 argumentos.
statements
-
As instruções que formam o corpo da função.
Descrição
Geradores são funções cuja execução pode ser interrompida e posteriormente reconduzida. Seus contextos (de associações de variáveis) ficarão salvos entre cada recondução.
Geradores em JavaScript — especialmente quando combinados com Promises — são uma ferramenta muito poderosa para programação assíncrona, por mitigarem — se não eliminarem — problemas com callbacks, como o Callback Hell e Inversão de Controle. Funções async
são fundamentadas nisso.
Chamar uma função geradora não executa seu conteúdo imediatamente; ao invés disso um objeto iterator é retornado. Quando o método next()
do objeto iterator é chamado, o conteúdo da função do gerador é executado até a primeira expressão yield
, que especifica o valor a ser devolvido do iterator ou com yield*
que delega para outra função geradora. O método next()
retorna um objeto com uma propriedade value
contendo o valor retornado e a propriedade boolean: done
indicando se o gerador produziu seu último valor. Chamar o método next()
com um argumento resumirá a execução da função geradora, substituindo a expressão yield
onde a execução foi pausada com o argumento de next()
.
Uma expressão return
em um gerador, quando executada, fará com que o gerador termine (isto é, a propriedade done
do objeto retornado será atribuído com o valor true
). Se um valor foi retornado, este será usado como propriedade value
do objeto retornado pelo gerador. Semelhantemente a uma expressão return
, um erro lançado dentro do gerador o terminará — a não ser que tratado no corpo do gerador. Quando um gerador estiver terminado, chamadas next
subsequentes não executarão nenhum código do gerador, retornarão simplesmente um objeto da seguinte forma: {value: undefined, done: true}
.
Exemplos
Exemplo simples
function* idMaker() {
var index = 0;
while (true) yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ...
Exemplo com yield*
function* outroGerador(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* gerador(i) {
yield i;
yield* outroGerador(i);
yield i + 10;
}
var gen = gerador(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
Passando argumentos em geradores
function* logGenerator() { console.log(0); console.log(1, yield); console.log(2, yield); console.log(3, yield); } var gen = logGenerator(); // a primeira chamada next é executada desde o início da função // até a primeira declaração yield gen.next(); // 0 gen.next('pretzel'); // 1 pretzel gen.next('california'); // 2 california gen.next('mayonnaise'); // 3 mayonnaise
Declaração de retono em um gerador
function* yieldAndReturn() { yield "Y"; return "R"; yield "unreachable"; } var gen = yieldAndReturn() console.log(gen.next()); // { value: "Y", done: false } console.log(gen.next()); // { value: "R", done: true } console.log(gen.next()); // { value: undefined, done: true }
Geradores não possuem construtor
function* f() {} var obj = new f; // lança o TypeError: f não é construtor
Gerador definido em uma expressão
const foo = function* () { yield 10; yield 20; }; const bar = foo(); console.log(bar.next()); // {value: 10, done: false}
Especificações
Specification |
---|
ECMAScript Language Specification # sec-generator-function-definitions |
Compatibilidade com navegadores
BCD tables only load in the browser
Observações específicas Firefox
Generators e iterators no Firefox em versões anteriores a 26
Versões mais antigas do Firefox implementam uma versão antiga da proposta de generators. Na versão mais antiga, generators foram intruídos a usarem a palavra chave function
(sem um asterísco) dentre outras diferenças.
O retorno do objeto IteratorResult
ao invés de um throw
Iniciando com Gecko 29, o generator finalizado não lança mais um TypeError
"generator has already finished". Ao invés disso, ele retorna um objeto IteratorResult
, como por exemplo { value: undefined, done: true }
(Erro do Firefox 958951).
Veja também
function* expression
-
GeneratorFunction
object yield
yield*
-
Function
object function declaration
function expression
Functions and function scope
-
Outras fontes na web:
- Regenerator um ES6 generator que compila para ES5
- Forbes Lindesay: Promises and Generators: control flow utopia — JSConf EU 2013
- Hemanth.HM: The New gen of *gen(){}
- Task.js