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
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
funcsynchron einen Wert zurückgibt; - bereits abgelehnt ist, wenn
funcsynchron einen Fehler auslöst; - asynchron erfüllt oder abgelehnt wird, wenn
funcein Promise zurückgibt. Der Rückgabewert wird zu einem Promise aufgelöst. Das bedeutet, dass integriertePromise-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:
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:
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:
Promise.try(func);
Beachten Sie, dass Promise.try() trotz großer Ähnlichkeit nicht dem Folgenden entspricht:
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:
Promise.try(() => func(arg1, arg2));
können Sie Folgendes schreiben:
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:
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:
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):
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:
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> |