Promise.withResolvers()
Baseline 2024
Newly available
Since March 2024, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Die statische Methode Promise.withResolvers()
gibt ein Objekt zurück, das ein neues Promise
-Objekt sowie zwei Funktionen zum Auflösen oder Ablehnen dieses Promise enthält, entsprechend den zwei Parametern, die dem 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;
});
Es ist jedoch kürzer und erfordert nicht die Verwendung von let
.
Der Hauptunterschied bei der Verwendung von Promise.withResolvers()
besteht darin, dass die Auflösungs- und Ablehnungsfunktionen nun im selben Gültigkeitsbereich wie das Promise selbst leben, anstatt einmal innerhalb des Executors erstellt und verwendet zu werden. Dies kann einige fortgeschrittene Anwendungsfälle ermöglichen, wie zum Beispiel deren Wiederverwendung für sich wiederholende Ereignisse, insbesondere bei Streams und Queues. Dies führt auch im Allgemeinen zu weniger Verschachtelung, als wenn viele Logiken innerhalb des Executors umschlossen werden.
Promise.withResolvers()
ist generisch und unterstützt das Subclassing, was bedeutet, dass es auf Unterklassen von Promise
aufgerufen werden kann und das Ergebnis ein Promise des Unterklassen-Typs enthalten wird. Dazu muss der Konstruktor der Unterklasse die gleiche Signatur wie der Promise()
-Konstruktor implementieren — das heißt, er muss eine einzelne executor
-Funktion akzeptieren, die mit den resolve
- und reject
-Rückrufen als Parameter aufgerufen werden kann.
Beispiele
Umwandlung eines Streams in ein asynchrones Iterable
Der Anwendungsfall von Promise.withResolvers()
besteht darin, wann Sie ein Promise haben, das von einem Ereignis-Listener aufgelöst oder abgelehnt werden sollte, der nicht innerhalb des Promise-Executors umschlossen werden kann. Das folgende Beispiel transformiert einen Node.js-lesbaren Stream in ein asynchrones Iterable. Jedes promise
repräsentiert hier einen einzelnen Datenblock, und jedes Mal, wenn der aktuelle Block gelesen wird, wird ein neues Promise für den nächsten Block erstellt. Beachten Sie, wie die Ereignis-Listener nur einmal angefügt werden, aber tatsächlich jede Version der resolve
- und reject
-Funktionen jedes Mal aufrufen.
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());
}
}
Aufruf von withResolvers() auf einem Nicht-Promise-Konstruktor
Promise.withResolvers()
ist eine generische Methode. Sie kann auf jedem Konstruktor aufgerufen werden, der die gleiche Signatur wie der Promise()
-Konstruktor implementiert. Zum Beispiel können wir sie auf einem Konstruktor aufrufen, der console.log
als die resolve
- und reject
-Funktionen an den 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),
);
}
}
const { promise, resolve, reject } = Promise.withResolvers.call(NotPromise);
resolve("hello");
// Logs: Resolved hello
Spezifikationen
Specification |
---|
ECMAScript Language Specification # sec-promise.withResolvers |
Browser-Kompatibilität
BCD tables only load in the browser