Start · Sprachen · JavaScript · Referenz · new AsyncGeneratorFunction()

new AsyncGeneratorFunction()

Methode

Der Konstruktor <code>AsyncGeneratorFunction()</code> erzeugt zur Laufzeit aus Zeichenketten eine neue asynchrone Generatorfunktion (<code>async function*</code>).

seit JavaScript ES2018 Kategorie: method-property

Signatur

new AsyncGeneratorFunction(...argNames, functionBody)

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

Typ
AsyncGeneratorFunction
Beschreibung
Eine neue asynchrone Generatorfunktion. Ihr Aufruf liefert ein 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();
1 2 3

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();
{ value: 10, done: false } { value: 15, done: false } { value: undefined, done: true } true

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();
[ 2, 4, 6 ]

// 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 einen EvalError.
  • Kein globaler Name: Ein Aufruf von AsyncGeneratorFunction ohne vorheriges Ermitteln über .constructor führt zu einem ReferenceError.
  • 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.