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

new AsyncFunction()

Methode

Der <code>AsyncFunction()</code>-Konstruktor erzeugt zur Laufzeit aus Zeichenketten eine neue asynchrone Funktion, die ein <code>Promise</code> zurückgibt.

seit JavaScript ES2017 Kategorie: method-property

Signatur

new AsyncFunction(arg1, arg2, /* …, */ argN, functionBody)

Beschreibung

AsyncFunction ist kein globales Objekt. Man erreicht den Konstruktor über den Prototyp einer beliebigen asynchronen Funktion: const AsyncFunction = async function () {}.constructor;. Der Konstruktor funktioniert wie Function(): Die letzte Zeichenkette ist der Funktionsrumpf, alle vorherigen sind Parameternamen. Im Rumpf ist await erlaubt.

Der Aufruf mit oder ohne new liefert dasselbe Ergebnis. Die erzeugte Funktion läuft immer im globalen Gültigkeitsbereich. Sie kann also nicht auf lokale Variablen der Stelle zugreifen, an der sie erzeugt wurde. Darin unterscheidet sie sich von eval() und von normalen async-Funktionsausdrücken, die einen Closure bilden.

Sinnvoll ist der Konstruktor nur in Sonderfällen, zum Beispiel für Code-Generatoren, REPLs, Plugin- oder Skript-Systeme und Sandbox-Werkzeuge, in denen asynchroner Quelltext erst zur Laufzeit vorliegt. Im normalen Anwendungscode sind async function-Deklarationen oder asynchrone Pfeilfunktionen schneller, sicherer und besser lesbar.

Parameter

Name Typ Default Beschreibung
$arg1, …, argN string Namen der formalen Parameter als Zeichenketten. Jeder Wert muss eine gültige Parameterliste sein, z. B. "a", "a, b", "x = 1" oder "...rest".
$functionBody string "" Quelltext des Funktionsrumpfs als Zeichenkette. Darin sind await und return erlaubt.

Rückgabewert

Typ
AsyncFunction
Beschreibung
Eine neue asynchrone Funktion. Jeder Aufruf dieser Funktion gibt ein Promise zurück.

Beispiele

Konstruktor beschaffen und Funktion erzeugen

const AsyncFunction = async function () {}.constructor;

const warte = (ms) => new Promise((r) => setTimeout(r, ms));
globalThis.warte = warte; // global, da kein Closure

const addiereVerzoegert = new AsyncFunction(
  "a",
  "b",
  "await warte(100); return a + b;"
);

const ergebnis = await addiereVerzoegert(2, 3);
console.log(ergebnis);
console.log(addiereVerzoegert instanceof AsyncFunction);
5 true

Benutzerskript in einem Plugin-System ausführen

const AsyncFunction = (async () => {}).constructor;

// Skript z. B. aus einer vertrauenswürdigen Konfiguration
const skript = `
  const res = await api.holeDaten(id);
  return res.name.toUpperCase();
`;

const api = {
  holeDaten: async (id) => ({ id, name: `nutzer-${id}` }),
};

// Kontext explizit als Parameter übergeben
const plugin = new AsyncFunction("api", "id", skript);
console.log(await plugin(api, 42));
NUTZER-42

Kein Zugriff auf lokale Variablen

const AsyncFunction = async function () {}.constructor;

const test = async () => {
  const geheim = "lokal";
  const fn = new AsyncFunction("return typeof geheim;");
  return fn();
};

console.log(await test());
undefined

// Wichtig · Fallstricke

  • Sicherheit: Der Konstruktor führt beliebigen Quelltext aus, ähnlich wie eval(). Übergib niemals ungeprüfte Benutzereingaben, sonst entstehen Code-Injection- und XSS-Lücken.
  • CSP: Ohne 'unsafe-eval' in der script-src-Direktive der Content Security Policy wirft der Aufruf einen EvalError. Dasselbe passiert in manchen Umgebungen wie Browser-Erweiterungen mit Manifest V3.
  • AsyncFunction ist kein globaler Bezeichner. new AsyncFunction() ohne vorherige Zuweisung wirft einen ReferenceError.
  • Die erzeugte Funktion hat keinen Closure. Sie sieht nur globale Variablen, alles andere musst du als Parameter übergeben.
  • Syntaxfehler im Rumpf treten schon beim Erzeugen auf (SyntaxError), nicht erst beim Aufruf.
  • Leistung: Der Code wird bei jedem Konstruktoraufruf neu geparst. Erzeuge Funktionen deshalb möglichst einmal und verwende sie wieder.
  • Unterstützt ab ES2017 in allen modernen Browsern und in Node.js 7.6+.