Signatur
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
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);
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));
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());
// 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 derscript-src-Direktive der Content Security Policy wirft der Aufruf einenEvalError. Dasselbe passiert in manchen Umgebungen wie Browser-Erweiterungen mit Manifest V3. AsyncFunctionist kein globaler Bezeichner.new AsyncFunction()ohne vorherige Zuweisung wirft einenReferenceError.- 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+.