Promise.try()
Limited availability
This feature is not Baseline because it does not work in some of the most widely-used browsers.
Experimentell: Dies ist eine experimentelle Technologie
Überprüfen Sie die Browser-Kompatibilitätstabelle sorgfältig, bevor Sie diese produktiv verwenden.
Die statische Methode Promise.try()
nimmt einen Callback beliebiger Art entgegen (gibt zurück oder wirft, synchron oder asynchron) und umhüllt dessen Ergebnis in einem Promise
.
Syntax
Promise.try(func)
Promise.try(func, arg1)
Promise.try(func, arg1, arg2)
Promise.try(func, arg1, arg2, /* …, */ argN)
Parameter
Rückgabewert
Ein Promise
, der:
- Bereits erfüllt ist, wenn
func
synchron einen Wert zurückgibt. - Bereits abgelehnt ist, wenn
func
synchron einen Fehler wirft. - Asynchron erfüllt oder abgelehnt ist, wenn
func
einpromise
zurückgibt.
Beschreibung
Es kann sein, dass Sie eine API haben, die einen Callback benötigt. Der Callback kann entweder synchron oder asynchron sein. Sie möchten alles einheitlich handhaben, indem Sie das Ergebnis in ein Promise einhüllen. Der direkteste Weg könnte Promise.resolve(func())
sein. Das Problem ist, dass wenn func()
synchron einen Fehler wirft, dieser Fehler nicht abgefangen und in ein abgelehntes Promise umgewandelt würde.
Der häufige Ansatz (das Heben eines Funktionsaufrufergebnisses in ein Promise, erfüllt oder abgelehnt) sieht oft so aus:
new Promise((resolve) => resolve(func()));
Aber Promise.try()
ist hier hilfreicher:
Promise.try(func);
Für den eingebauten Promise()
-Konstruktor werden Fehler, die vom Executor geworfen werden, automatisch abgefangen und in Ablehnungen umgewandelt. Daher sind diese beiden Ansätze größtenteils äquivalent, außer dass Promise.try()
kürzer und lesbarer ist.
Beachten Sie, dass Promise.try()
nicht äquivalent zu diesem ist, obwohl es sehr ähnlich ist:
Promise.resolve().then(func);
Der Unterschied ist, dass der Callback, der an then()
übergeben wird, 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 sofort auf, wenn es möglich ist.
Promise.try()
, in Kombination mit catch()
und finally()
, kann verwendet werden, um sowohl synchrone als auch asynchrone Fehler in einer einzigen Kette zu behandeln und die Fehlerbehandlung von Promises fast wie bei synchronen Fehlern erscheinen zu lassen.
Wie setTimeout()
akzeptiert Promise.try()
zusätzliche Argumente, die an den Callback übergeben werden. Das bedeutet, dass anstatt dies zu tun:
Promise.try(() => func(arg1, arg2));
Sie können dies tun:
Promise.try(func, arg1, arg2);
Die beiden sind äquivalent, aber letzteres vermeidet die Erzeugung einer zusätzlichen Closure und ist effizienter.
Beispiele
Verwendung von Promise.try()
Das folgende Beispiel nimmt einen Callback, "hebt" ihn in ein Promise, verarbeitet das Ergebnis und führt eine Fehlerbehandlung durch:
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");
});
In async/await würde derselbe Code so aussehen:
async function doSomething(action) {
try {
const result = await action();
console.log(result);
} catch (error) {
console.error(error);
} finally {
console.log("Done");
}
}
Aufruf von try() auf einem Nicht-Promise-Konstruktor
Promise.try()
ist eine generische Methode. Sie kann auf jeden Konstruktor aufgerufen werden, der dieselbe Signatur wie der Promise()
-Konstruktor implementiert.
Das folgende ist eine etwas genauere Annäherung an das tatsächliche Promise.try()
(obwohl es immer noch nicht als Polyfill verwendet werden sollte):
Promise.try = function (func) {
return new this((resolve, reject) => {
try {
resolve(func());
} catch (error) {
reject(error);
}
});
};
Aufgrund der Art und Weise, wie Promise.try()
implementiert ist (d. h. das try...catch
), können wir Promise.try()
sicher mit diesem Operator auf jeden benutzerdefinierten Konstruktor anwenden und es wird niemals synchron einen Fehler werfen.
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),
);
}
}
const p = Promise.try.call(NotPromise, () => "hello");
// Logs: Resolved hello
const p2 = Promise.try.call(NotPromise, () => {
throw new Error("oops");
});
// Logs: Rejected Error: oops
Im Gegensatz zu Promise()
behandelt dieser NotPromise()
-Konstruktor nicht auf elegante Weise Ausnahmen, die beim Ausführen des Executors auftreten. Aber trotz des throw
fängt Promise.try()
immer noch die Ausnahme ab und übergibt sie an reject()
, um sie zu protokollieren.
Spezifikationen
Specification |
---|
Promise.try # sec-promise.try |
Browser-Kompatibilität
BCD tables only load in the browser