--- title: function* slug: Web/JavaScript/Reference/Statements/function* tags: - ECMAScript6 - Function - Iterator - JavaScript - Statement translation_of: Web/JavaScript/Reference/Statements/function* ---
A declaração function*
(palavra chave function
seguida de um asterisco) define uma função geradora (generator function), que retorna um objeto {{jsxref("Global_Objects/Generator","Generator")}}.
{{EmbedInteractiveExample("pages/js/statement-functionasterisk.html")}}
Você também pode definir funções geradoras usando o construtor {{jsxref("GeneratorFunction")}} ou a sintaxe da expressão de uma função.
function* name([param[, param[, ... param]]]) { statements }
name
param
statements
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 {{jsxref("Operators/yield", "yield")}}, que especifica o valor a ser devolvido do iterator ou com {{jsxref("Operators/yield*", "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}
.
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
// ...
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
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
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 }
function* f() {}
var obj = new f; // lança o TypeError: f não é construtor
const foo = function* () {
yield 10;
yield 20;
};
const bar = foo();
console.log(bar.next()); // {value: 10, done: false}
Especificação | Status | Comentário |
---|---|---|
{{SpecName('ES2015', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ES2015')}} | Definição inicial. |
{{SpecName('ES2016', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ES2016')}} | Mudou para que generators não tenham a armadilha de [[Construct]] e irão lançar um erro, quando usados com new . |
{{SpecName('ESDraft', '#sec-generator-function-definitions', 'function*')}} | {{Spec2('ESDraft')}} |
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.
IteratorResult
ao invés de um throwIniciando com Gecko 29 {{geckoRelease(29)}}, o generator finalizado não lança mais um {{jsxref("TypeError")}} "generator has already finished". Ao invés disso, ele retorna um objeto IteratorResult
, como por exemplo { value: undefined, done: true }
({{bug(958951)}}).