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

js
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*

js
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

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
function* statement
IteratorResult object instead of throwing
Not constructable with new (ES2016)
Trailing comma in parameters

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

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