Promise.withResolvers()
Baseline
2024
最近利用可能
March 2024以降、この機能は最新のバージョンの端末およびブラウザーで動作します。古い端末やブラウザーでは動作しないことがあります。
Promise.withResolvers() 静的メソッドは、新しい Promise オブジェクトと、Promise() コンストラクターの実行子に渡す 2 つの引数に対応する、解決または拒否の 2 つの関数を含むオブジェクトを返します。
構文
Promise.withResolvers()
引数
なし。
返値
以下のプロパティを格納するプレーンオブジェクトです。
解説
Promise.withResolvers() は以下のコードと全く同じです。
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
ただし、より簡潔であり、let を使用する必要はありません。
Promise.withResolvers() を使用する場合の主な違いは、解決関数や拒否関数を実行環境で一度ずつ作成して使用するのではなく、プロミス自身と同じスコープで使用することです。これにより、特にストリームやキューで繰り返し発生するイベントに使用する場合など、より高度な用途が可能になります。また、これは一般的に、実行環境内で多くのロジックをラップするよりも入れ子が少なくなります。
Promise.withResolvers() は汎用的であり、サブクラスに対応しています。つまり、Promise のサブクラスで呼び出すことができ、その結果にはサブクラスの型のプロミスが格納されます。そのためには、サブクラスのコンストラクターは Promise() コンストラクターと同じシグネチャを実装する必要があります。resolve と reject コールバックを引数として呼び出される単一の実行関数を受け入れます。
例
>ストリームを非同期反復可能オブジェクトに変換
Promise.withResolvers() の使用する用途は、プロミスの実行環境内にラップできないイベントリスナーによって解決または拒否されたプロミスがある場合です。次の例は、Node.js の読み取り可能なストリームを非同期反復可能オブジェクトに変換します。ここでの各プロミスは利用できるデータの単一のバッチを表し、現在のバッチが読み込まれるたびに、次のバッチのために新しいプロミスが作成されます。イベントリスナーは一度しかアタッチされませんが、実際には毎回、resolve 関数と reject 関数の異なるバージョンを呼び出していることに注意してください。
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());
}
}
Promise 以外のコンストラクターに対する withResolvers() の呼び出し
Promise.withResolvers() は汎用メソッドです。これは Promise() コンストラクターと同じシグネチャを実装した任意のコンストラクターで呼び出すことができます。例えば、 console.log を resolve と reject 関数として executor に渡すコンストラクターに対して呼び出すことができます。
class NotPromise {
constructor(executor) {
// "resolve" 関数と "reject" 関数はネイティブのプロミスと同じような
// 振る舞いはしませんが、Promise.withResolvers() はそれらをそのまま返します。
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
}
const { promise, resolve, reject } = Promise.withResolvers.call(NotPromise);
resolve("hello");
// Logs: Resolved hello
仕様書
| 仕様書 |
|---|
| ECMAScript® 2027 Language Specification> # sec-promise.withResolvers> |