Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Promise.try()

Baseline 2025
Neu verfügbar

Seit Januar 2025 funktioniert diese Funktion auf aktuellen Geräten und in aktuellen Browserversionen. Auf älteren Geräten oder in älteren Browsern funktioniert sie möglicherweise nicht.

Die statische Methode Promise.try() nimmt eine Callback-Funktion entgegen, die einen Wert zurückgeben oder einen Fehler auslösen kann – synchron oder asynchron – und löst ihr Ergebnis zu einem Promise auf.

Syntax

js
Promise.try(func)
Promise.try(func, arg1)
Promise.try(func, arg1, arg2)
Promise.try(func, arg1, arg2, /* …, */ argN)

Parameter

func

Eine Funktion, die synchron mit den übergebenen Argumenten (arg1, arg2, …, argN) aufgerufen wird. Sie kann einen Wert zurückgeben, einen Fehler auslösen oder ein Promise zurückgeben.

arg1, arg2, …, argN

Argumente, die an func übergeben werden.

Rückgabewert

Ein Promise, das:

  • bereits erfüllt ist, wenn func synchron einen Wert zurückgibt;
  • bereits abgelehnt ist, wenn func synchron einen Fehler auslöst;
  • asynchron erfüllt oder abgelehnt wird, wenn func ein Promise zurückgibt. Der Rückgabewert wird zu einem Promise aufgelöst. Das bedeutet, dass integrierte Promise-Objekte unverändert zurückgegeben werden.

Beschreibung

Möglicherweise verwenden Sie eine API, die eine Callback-Funktion entgegennimmt. Diese kann synchron oder asynchron sein. Um beide Fälle einheitlich zu behandeln, möchten Sie das Ergebnis in ein Promise einbinden. Der naheliegendste Weg ist möglicherweise Promise.resolve(func()). Wenn func() jedoch synchron einen Fehler auslöst, wird dieser nicht abgefangen und in ein abgelehntes Promise umgewandelt.

Sie können den Ausdruck in try...catch einschließen:

js
let result;
try {
  result = Promise.resolve(func());
} catch (error) {
  result = Promise.reject(error);
}

Das Problem ist, dass try...catch kein Ausdruck ist. Sie können es daher nicht direkt dort verwenden, wo ein Ausdruck erwartet wird, etwa als Argument einer anderen Funktion.

Um das Ergebnis eines Funktionsaufrufs in ein erfülltes oder abgelehntes Promise zu überführen, wird daher häufiger Folgendes verwendet:

js
new Promise((resolve) => resolve(func()));

Beim integrierten Promise()-Konstruktor werden Fehler, die der Executor auslöst, automatisch abgefangen und in Ablehnungen umgewandelt. Damit werden auch synchrone Fehler behandelt. Allerdings wird dabei ausnahmslos ein neues Promise-Objekt erstellt, was unnötig ist, wenn func() bereits ein Promise zurückgibt. Promise.resolve() vermeidet diese zusätzliche Einbindung in ein Promise.

Promise.try() ist nahezu gleichwertig mit dem Ansatz über try...catch, ist aber kürzer und kann als Ausdruck verwendet werden:

js
Promise.try(func);

Beachten Sie, dass Promise.try() trotz großer Ähnlichkeit nicht dem Folgenden entspricht:

js
Promise.resolve().then(func);

Der Unterschied besteht darin, dass die an then() übergebene Callback-Funktion immer asynchron aufgerufen wird, während der Executor des Promise()-Konstruktors synchron aufgerufen wird. Auch Promise.try ruft die Funktion synchron auf und löst das Promise nach Möglichkeit sofort auf.

Zusammen mit catch() und finally() kann Promise.try() synchrone und asynchrone Fehler in einer einzigen Promise-Kette behandeln. Dadurch ähnelt die Fehlerbehandlung bei Promises der synchronen Fehlerbehandlung.

Wie setTimeout() akzeptiert Promise.try() zusätzliche Argumente, die an die Callback-Funktion übergeben werden. Statt Folgendes zu schreiben:

js
Promise.try(() => func(arg1, arg2));

können Sie Folgendes schreiben:

js
Promise.try(func, arg1, arg2);

Beide Varianten sind gleichwertig. Die zweite vermeidet jedoch die Erstellung einer zusätzlichen Closure und ist effizienter.

Promise.try() ist generisch und unterstützt Unterklassen. Es kann also für Unterklassen von Promise aufgerufen werden; das Ergebnis enthält dann ein Promise des Unterklassentyps. Dazu muss der Konstruktor der Unterklasse dieselbe Signatur wie der Promise()-Konstruktor implementieren: Er muss eine einzelne executor-Funktion entgegennehmen, die mit den Callback-Funktionen resolve und reject als Parametern aufgerufen werden kann.

Beispiele

Promise.try() verwenden

Das folgende Beispiel nimmt eine Callback-Funktion entgegen, überführt sie in ein Promise, verarbeitet das Ergebnis und behandelt mögliche Fehler:

js
function doSomething(action) {
  return Promise.try(action)
    .then((result) => console.log(result))
    .catch((error) => console.error(error))
    .finally(() => console.log("Done"));
}

doSomething(() => "Sync result");

doSomething(() => {
  throw new Error("Sync error");
});

doSomething(async () => "Async result");

doSomething(async () => {
  throw new Error("Async error");
});

Mit async/await sähe derselbe Code so aus:

js
async function doSomething(action) {
  try {
    const result = await action();
    console.log(result);
  } catch (error) {
    console.error(error);
  } finally {
    console.log("Done");
  }
}

try() für einen Konstruktor aufrufen, der kein Promise-Konstruktor ist

Promise.try() ist eine generische Methode. Sie kann für jeden Konstruktor aufgerufen werden, der dieselbe Signatur wie der Promise()-Konstruktor implementiert.

Das Folgende ist eine etwas genauere Annäherung an die tatsächliche Implementierung von Promise.try() (sollte aber dennoch nicht als Polyfill verwendet werden):

js
Promise.try = function (func, ...args) {
  let result;
  try {
    result = func(...args);
  } catch (error) {
    return Promise.reject.call(this, error);
  }
  return Promise.resolve.call(this, result);
};

Promise.try() verwendet Promise.resolve() und Promise.reject(), um den Rückgabewert zu erzeugen. Beide Funktionen sind generisch.

Beispielsweise können wir die Methode für einen Konstruktor aufrufen, der console.log als resolve- und reject-Funktion an executor übergibt:

js
class NotPromise {
  constructor(executor) {
    // The "resolve" and "reject" functions behave nothing like the native
    // promise's, but Promise.try() just calls resolve
    executor(
      (value) => console.log("Resolved", value),
      (reason) => console.log("Rejected", reason),
    );
  }

  static try = Promise.try;
}

const p = NotPromise.try(() => "hello");
// Logs: Resolved hello
// p is a NotPromise instance

const p2 = NotPromise.try(() => {
  throw new Error("oops");
});
// Logs: Rejected Error: oops
// p2 is a NotPromise instance

Spezifikationen

Spezifikation
ECMAScript® 2027 Language Specification
# sec-promise.try

Browser-Kompatibilität

Siehe auch