Promise.withResolvers()
Baseline
Weitgehend verfügbar
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit März 2024 browserübergreifend verfügbar.
Die statische Methode Promise.withResolvers() gibt ein Objekt zurück, das ein neues Promise-Objekt und zwei Funktionen enthält, mit denen dieses erfüllt oder zurückgewiesen werden kann. Die Funktionen entsprechen den beiden Parametern, die an den Executor des Promise()-Konstruktors übergeben werden.
Syntax
Promise.withResolvers()
Parameter
Keine.
Rückgabewert
Ein einfaches Objekt mit den folgenden Eigenschaften:
Beschreibung
Promise.withResolvers() entspricht genau dem folgenden Code:
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
Allerdings ist die Methode kürzer und erfordert keine Verwendung von let.
Der wesentliche Unterschied bei der Verwendung von Promise.withResolvers() besteht darin, dass sich die Funktionen zum Erfüllen und Zurückweisen nun im selben Gültigkeitsbereich wie das Promise selbst befinden, statt innerhalb des Executors erstellt und einmalig verwendet zu werden. Dies ermöglicht möglicherweise fortgeschrittenere Anwendungsfälle, etwa wenn die Funktionen für wiederkehrende Ereignisse wiederverwendet werden, insbesondere bei Streams und Warteschlangen. Außerdem führt dies im Allgemeinen zu weniger Verschachtelung, als wenn umfangreiche Logik im Executor untergebracht wird.
Promise.withResolvers() ist generisch und unterstützt Unterklassen. Die Methode kann daher 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 Callbacks resolve und reject als Parametern aufgerufen werden kann.
Beispiele
>Einen Stream in ein asynchrones Iterable umwandeln
Ein Anwendungsfall für Promise.withResolvers() liegt vor, wenn ein Promise durch einen Event-Listener erfüllt oder zurückgewiesen werden soll, der sich nicht in den Promise-Executor einbinden lässt. Das folgende Beispiel wandelt einen lesbaren Stream von Node.js in ein asynchrones Iterable um. Jedes promise steht dabei für einen einzelnen verfügbaren Datenblock. Sobald der aktuelle Block gelesen wurde, wird ein neues Promise für den nächsten Block erstellt. Beachten Sie, dass die Event-Listener nur einmal registriert werden, bei jedem Aufruf aber eine andere Version der Funktionen resolve und reject verwenden.
async function* readableToAsyncIterable(stream) {
let { promise, resolve, reject } = Promise.withResolvers();
stream.on("error", (error) => reject(error));
stream.on("end", () => resolve());
stream.on("readable", () => resolve());
while (stream.readable) {
await promise;
let chunk;
while ((chunk = stream.read())) {
yield chunk;
}
({ promise, resolve, reject } = Promise.withResolvers());
}
}
withResolvers() mit einem Konstruktor aufrufen, der kein Promise-Konstruktor ist
Promise.withResolvers() ist eine generische Methode. Sie kann mit jedem Konstruktor aufgerufen werden, der dieselbe Signatur wie der Promise()-Konstruktor implementiert. Beispielsweise können wir sie mit einem Konstruktor aufrufen, der console.log als Funktionen resolve und reject an executor übergibt:
class NotPromise {
constructor(executor) {
// The "resolve" and "reject" functions behave nothing like the native
// promise's, but Promise.withResolvers() just returns them, as is.
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
static withResolvers = Promise.withResolvers;
}
const { promise, resolve, reject } = NotPromise.withResolvers();
resolve("hello");
// Logs: Resolved hello
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-promise.withResolvers> |