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

new Promise()

Methode

Der <code>Promise()</code>-Konstruktor erstellt ein neues <code>Promise</code>-Objekt und wird vor allem genutzt, um callback-basierte APIs in Promises zu verpacken.

seit JavaScript ES2015 Kategorie: method-property

Signatur

new Promise(executor)

Beschreibung

Der Konstruktor new Promise(executor) erzeugt ein Promise, dessen Zustand (erfüllt oder abgelehnt) über die Funktionen resolve und reject gesteuert wird. Diese beiden Funktionen bekommt die übergebene Executor-Funktion als Argumente. Der Executor wird sofort und synchron während des Konstruktoraufrufs ausgeführt.

Der wichtigste Einsatzzweck ist das Promisifizieren älterer APIs, die mit Callbacks oder Events arbeiten, z. B. setTimeout, FileReader, XMLHttpRequest oder Node.js-Callbacks im Stil (err, result). Liefert eine Funktion bereits ein Promise (z. B. fetch()), brauchst du keinen eigenen Konstruktor, sondern verkettest direkt mit then() bzw. await.

Ein Promise lässt sich nur einmal festlegen: Weitere Aufrufe von resolve oder reject danach werden ignoriert. Wird resolve mit einem anderen Promise oder einem Thenable aufgerufen, übernimmt das neue Promise dessen Zustand. Wirft der Executor eine Ausnahme, wird das Promise automatisch abgelehnt – es sei denn, es wurde vorher schon festgelegt.

Parameter

Name Typ Default Beschreibung
$executor Pflicht (resolve: (value?: any) => void, reject: (reason?: any) => void) => void Funktion, die synchron vom Konstruktor aufgerufen wird. Sie erhält resolve (erfüllt das Promise mit einem Wert) und reject (lehnt das Promise mit einem Grund ab, idealerweise ein Error). Ihr Rückgabewert wird ignoriert.

Rückgabewert

Typ
Promise
Beschreibung
Ein neues Promise-Objekt, das zunächst ausstehend (pending) ist und erfüllt bzw. abgelehnt wird, sobald resolve bzw. reject aufgerufen wird.

Beispiele

setTimeout als Promise verpacken (sleep)

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const main = async () => {
  console.log('Start');
  await sleep(1000);
  console.log('Eine Sekunde später');
};

main();
Start Eine Sekunde später

Node.js-Callback-API promisifizieren

import { readFile } from 'node:fs';

const readFileAsync = (path) =>
  new Promise((resolve, reject) => {
    readFile(path, 'utf8', (err, data) => {
      if (err) {
        reject(err);
        return;
      }
      resolve(data);
    });
  });

try {
  const text = await readFileAsync('./config.json');
  console.log(JSON.parse(text));
} catch (err) {
  console.error('Fehler beim Lesen:', err.message);
}
{ ... Inhalt von config.json ... }

Bild laden mit Event-Handlern

const loadImage = (src) =>
  new Promise((resolve, reject) => {
    const img = new Image();
    img.onload = () => resolve(img);
    img.onerror = () => reject(new Error(`Bild konnte nicht geladen werden: ${src}`));
    img.src = src;
  });

loadImage('/logo.png')
  .then((img) => console.log('Geladen:', img.naturalWidth, 'x', img.naturalHeight))
  .catch((err) => console.error(err.message));
Geladen: 256 x 256

Executor läuft synchron, Festlegung nur einmal

const p = new Promise((resolve, reject) => {
  console.log('Executor läuft');
  resolve('erster Wert');
  resolve('zweiter Wert'); // ignoriert
  reject(new Error('zu spät')); // ignoriert
});

console.log('Nach dem Konstruktor');
p.then((v) => console.log('Ergebnis:', v));
Executor läuft Nach dem Konstruktor Ergebnis: erster Wert

// Wichtig · Fallstricke

  • Nur mit new: Promise() ohne new wirft einen TypeError. Auch ein fehlender oder nicht aufrufbarer Executor führt zu einem TypeError.
  • Anti-Pattern „Promise-Konstruktor um ein Promise“: new Promise((res, rej) => fetch(url).then(res, rej)) ist überflüssig und fehleranfällig – gib einfach fetch(url) zurück.
  • Kein async-Executor: Bei new Promise(async (resolve) => { ... }) gehen Fehler nach dem ersten await verloren, da sie nicht zur Ablehnung des äußeren Promise führen.
  • Asynchrone Ausnahmen werden nicht abgefangen: Ein throw innerhalb eines setTimeout-Callbacks im Executor lehnt das Promise nicht ab – dort explizit reject() aufrufen.
  • Nach resolve/reject läuft der Code weiter: Mit return abbrechen, wenn danach nichts mehr passieren soll.
  • Mit Error-Objekten ablehnen, damit ein Stacktrace erhalten bleibt. Nicht behandelte Ablehnungen lösen unhandledrejection (Browser) bzw. in Node.js 15+ standardmäßig einen Prozessabbruch aus.
  • Für Node.js-Callbacks gibt es alternativ util.promisify(); seit ES2024 liefert Promise.withResolvers() resolve/reject außerhalb eines Executors.
  • Kompatibilität: in allen modernen Browsern und Node.js unterstützt, nicht im Internet Explorer (Polyfill nötig).