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.
Die function*
-Deklaration erstellt eine Bindung einer neuen Generatorfunktion mit einem gegebenen Namen. Eine Generatorfunktion kann beendet und später wieder aufgerufen werden, wobei ihr Kontext (variable Bindungen) über die erneuten Aufrufe hinweg gespeichert bleibt.
Sie können Generatorfunktionen auch mithilfe des function*
Ausdrucks definieren.
Probieren Sie es aus
function* generator(i) {
yield i;
yield i + 10;
}
const gen = generator(10);
console.log(gen.next().value);
// Expected output: 10
console.log(gen.next().value);
// Expected output: 20
Syntax
function* name(param0) {
statements
}
function* name(param0, param1) {
statements
}
function* name(param0, param1, /* …, */ paramN) {
statements
}
Hinweis: Generatorfunktionen haben keine Gegenstücke in Pfeilfunktionen.
Hinweis:
function
und *
sind separate Token, also können sie durch Leerzeichen oder Zeilenumbrüche getrennt werden.
Parameter
name
-
Der Funktionsname.
param
Optional-
Der Name eines formalen Parameters für die Funktion. Für die Syntax der Parameter siehe die Funktionen-Referenz.
statements
Optional-
Die Anweisungen, die den Körper der Funktion bilden.
Beschreibung
Eine function*
-Deklaration erzeugt ein GeneratorFunction
-Objekt. Jedes Mal, wenn eine Generatorfunktion aufgerufen wird, gibt sie ein neues Generator
-Objekt zurück, das dem Iterator-Protokoll entspricht. Wenn die next()
-Methode des Iterators aufgerufen wird, wird der Rumpf der Generatorfunktion bis zum ersten yield
-Ausdruck ausgeführt, der den aus dem Iterator zurückzugebenden Wert angibt oder mit yield*
an eine andere Generatorfunktion delegiert. Die next()
-Methode gibt ein Objekt mit einer value
-Eigenschaft zurück, das den übergebenen Wert enthält, und einer done
-Eigenschaft, die als boolean angibt, ob der Generator seinen letzten Wert übergeben hat. Das Aufrufen der next()
-Methode mit einem Argument setzt die Ausführung der Generatorfunktion fort, indem der yield
-Ausdruck, bei dem eine Ausführung unterbrochen wurde, durch das Argument von next()
ersetzt wird.
Generatoren in JavaScript sind — besonders in Kombination mit Promises — ein sehr mächtiges Werkzeug für die asynchrone Programmierung, da sie die Probleme mit Callbacks — wie Callback Hell und Inversion of Control — mildern, wenn nicht sogar ganz eliminieren. Eine noch einfachere Lösung für diese Probleme wird jedoch durch async functions erreicht.
Eine return
-Anweisung in einem Generator führt dazu, dass der Generator beendet ist (d.h. die done
-Eigenschaft des Objekts, das von ihm zurückgegeben wird, wird auf true
gesetzt). Wenn ein Wert zurückgegeben wird, wird er als value
-Eigenschaft des vom Generator zurückgegebenen Objekts gesetzt. Genau wie eine return
-Anweisung führt ein innerhalb des Generators ausgelöster Fehler dazu, dass der Generator beendet wird — es sei denn, er wird innerhalb des Rumpfes des Generators abgefangen. Wenn ein Generator beendet ist, führen nachfolgende next()
-Aufrufe keinen Code dieses Generators aus, sie geben nur ein Objekt der Form: {value: undefined, done: true}
zurück.
function*
-Deklarationen verhalten sich ähnlich wie function
-Deklarationen — sie werden an die Spitze ihres Bereichs gehoben und können überall in ihrem Bereich aufgerufen werden und sie können nur in bestimmten Kontexten erneut deklariert werden.
Beispiele
Einfaches Beispiel
function* idMaker() {
let index = 0;
while (true) {
yield index++;
}
}
const 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
// …
Beispiel mit yield*
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
const gen = generator(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
Übergabe von Argumenten an Generatoren
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
const gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next(); // 0
gen.next("pretzel"); // 1 pretzel
gen.next("california"); // 2 california
gen.next("mayonnaise"); // 3 mayonnaise
Return-Anweisung in einem Generator
function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
const 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 }
Generator als Objekteigenschaft
const someObj = {
*generator() {
yield "a";
yield "b";
},
};
const gen = someObj.generator();
console.log(gen.next()); // { value: 'a', done: false }
console.log(gen.next()); // { value: 'b', done: false }
console.log(gen.next()); // { value: undefined, done: true }
Generator als Objektmethode
class Foo {
*generator() {
yield 1;
yield 2;
yield 3;
}
}
const f = new Foo();
const gen = f.generator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Generator als berechnete Eigenschaft
class Foo {
*[Symbol.iterator]() {
yield 1;
yield 2;
}
}
const SomeObj = {
*[Symbol.iterator]() {
yield "a";
yield "b";
},
};
console.log(Array.from(new Foo())); // [ 1, 2 ]
console.log(Array.from(SomeObj)); // [ 'a', 'b' ]
Generatoren sind nicht konstruierbar
function* f() {}
const obj = new f(); // throws "TypeError: f is not a constructor
Generatorbeispiel
function* powers(n) {
// Endless loop to generate
for (let current = n; ; current *= n) {
yield current;
}
}
for (const power of powers(2)) {
// Controlling generator
if (power > 32) {
break;
}
console.log(power);
// 2
// 4
// 8
// 16
// 32
}
Spezifikationen
Specification |
---|
ECMAScript® 2026 Language Specification # sec-generator-function-definitions |
Browser-Kompatibilität
Siehe auch
- Funktionen Leitfaden
- Iteratoren und Generatoren Leitfaden
- Funktionen
GeneratorFunction
function*
Ausdruckfunction
async function
async function*
- Iterationsprotokolle
yield
yield*
Generator
- Regenerator auf GitHub
- Promises und Generators: Kontrollfluss-Utopie Präsentation von Forbes Lindesay bei JSConf (2013)
- Task.js auf GitHub
- You Don't Know JS: Async & Performance, Kap.4: Generators von Kyle Simpson