Signatur
Beschreibung
Der Konstruktor AsyncGeneratorFunction() erzeugt dynamisch eine neue async function*. Parameternamen und Funktionsrumpf werden als Zeichenketten übergeben und zur Laufzeit geparst. Das Ergebnis verhält sich wie eine per Deklaration geschriebene asynchrone Generatorfunktion: Ein Aufruf liefert ein AsyncGenerator-Objekt, das man mit for await...of oder mit next() durchlaufen kann.
Wichtig: AsyncGeneratorFunction ist keine globale Variable. An den Konstruktor kommt man nur über einen Umweg, z. B. const AsyncGeneratorFunction = async function* () {}.constructor; oder über Object.getPrototypeOf(async function* () {}).constructor.
Man kann den Konstruktor mit oder ohne new aufrufen, das Ergebnis ist dasselbe. Wie bei new Function() entstehen die Funktionen immer im globalen Gültigkeitsbereich. Sie bilden also keine Closure über den Kontext, in dem sie erzeugt wurden, und sehen nur globale Variablen.
Praktisch braucht man das nur selten, etwa für Code-Generatoren, Sandboxes, REPLs oder Lernumgebungen. Im normalen Anwendungscode schreibt man async function* direkt als Deklaration oder Ausdruck. Das ist schneller, sicherer und besser lesbar.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $argNames | string | Null oder mehr Zeichenketten mit gültigen Parameternamen. Sie können auch in einer einzigen Zeichenkette mit Kommas stehen, z. B. "a, b". Standardwerte, Restparameter (...rest) und Destrukturierung sind erlaubt. |
|
| $functionBody | string | "" | Der Funktionsrumpf als Zeichenkette. Er darf await, yield und yield* enthalten. Er ist immer das letzte Argument. |
Rückgabewert
AsyncGenerator-Objekt.Beispiele
Konstruktor ermitteln und Funktion erzeugen
// AsyncGeneratorFunction ist nicht global – über den Prototyp holen
const AsyncGeneratorFunction = async function* () {}.constructor;
const zaehler = new AsyncGeneratorFunction('start', 'ende', `
for (let i = start; i <= ende; i++) {
await new Promise((r) => setTimeout(r, 100));
yield i;
}
`);
const main = async () => {
for await (const n of zaehler(1, 3)) {
console.log(n);
}
};
main();
Manuelles Iterieren mit next()
const AsyncGeneratorFunction = Object.getPrototypeOf(async function* () {}).constructor;
const gen = AsyncGeneratorFunction('a, b', 'yield await Promise.resolve(a); yield a + b;');
const main = async () => {
const it = gen(10, 5);
console.log(await it.next());
console.log(await it.next());
console.log(await it.next());
console.log(gen instanceof AsyncGeneratorFunction);
};
main();
Globaler Gültigkeitsbereich – keine Closure
globalThis.faktor = 2;
const erzeuge = () => {
const faktor = 100; // lokal – für die dynamische Funktion unsichtbar
const AGF = async function* () {}.constructor;
return new AGF('werte', 'for (const w of werte) yield w * faktor;');
};
const main = async () => {
const verdopple = erzeuge();
const ergebnis = [];
for await (const x of verdopple([1, 2, 3])) ergebnis.push(x);
console.log(ergebnis);
};
main();
// Wichtig · Fallstricke
- Sicherheit: Der Konstruktor wertet Zeichenketten als Code aus und ist damit genauso riskant wie
eval(). Übergib niemals ungeprüfte Benutzereingaben, sonst droht Code-Injection bzw. XSS. - CSP: Wenn eine Content Security Policy ohne
'unsafe-eval'aktiv ist, wirft der Aufruf einenEvalError. - Kein globaler Name: Ein Aufruf von
AsyncGeneratorFunctionohne vorheriges Ermitteln über.constructorführt zu einemReferenceError. - Gültigkeitsbereich: Die erzeugten Funktionen sehen nur globale Variablen und keine lokalen Variablen aus dem Kontext, in dem sie erzeugt wurden.
- Syntaxfehler im Rumpf oder in den Parameternamen werfen beim Erzeugen einen
SyntaxError, nicht erst beim Aufruf. - Performance: Der Code wird bei jedem Konstruktor-Aufruf neu geparst, und Engines können ihn schlechter optimieren. Vermeide Aufrufe in Schleifen.
- Kompatibilität: ES2018. Wird von allen modernen Browsern und von Node.js ab Version 10 unterstützt.