mdn: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
## 概要
repo: https://github.com/tc39/proposal-promise-with-resolvers
`Promise.withResolvers()` メソッドは [[ECMAScript MOC|ECMAScript]] で現在 [[ECMAScriptプロポーザルのステージ|stage4]] の [[ECMAScriptのプロポーザル|プロポーザル]] として出ている [[JavaScript Promiseをコンストラクタの外側から解決|Promiseを外側から解決する]] テクニックをメソッドとして定義しているプロポーザルであり、[[ECMAScript 2024|ES2024]] で遂に追加された。
[[JavaScriptのPromiseオブジェクト MOC|Promise]] の resolution や rejection は Promise インスタンスを作成した後で設定したいことがある。これまでは以下のようなテクニックを使用する必要があった。
```js
// まずは束縛するための変数を定義
let promiseResolve, promiseReject;
const promise = new Promise((resolve, reject) => {
// resolve関数を外部の変数に束縛
promiseResolve = resolve;
// reject関数を外部の変数に束縛
promiseReject = reject;
});
// 外部から解決する
promiseResolve();
```
このパターンをビルトインメソッドとして使えるようにしたものが `Promise.withResolvers` である。このメソッドにより、Promise の解決や拒否を Promise インスタンスの生成後に簡単に自由に決めることができるようになる。
新しく追加された Promise の静的メソッドである `Promise.withResolvers()` では以下のように三つのオブジェクトを返すようにして、[[JavaScript オブジェクトの分割代入|オブジェクトの分割代入]] ができる。
```js
const {
promise,
resolve,
reject
} = Promise.withResolvers();
```
このプロポーザルでは、シンプルに `withResolvers` という [[JavaScript Objectの静的メソッド|静的メソッド]] で、[[JavaScript Promiseコンストラクタ|Promise constructor]] に対して、公開された解決関数と拒否関数と共に Promise オブジェクトを返す。
このメソッドは、委員会メンバーは `defer` や `deferred` と呼ばれているメソッドで、JS のエコシステムでユーティリティ関数でもそのように呼ばれている。
以下のような箇所で実際に作成されている。
[TypeScriptのユーティリティ関数](https://github.com/microsoft/TypeScript/blob/1d96eb489e559f4f61522edb3c8b5987bbe948af/src/harness/util.ts#L121-L129)
[Deno deferred](https://deno.land/
[email protected]/async/deferred.ts?source )
## シンタックス
```js
Promise.withResolvers();
```
引数
- なし
返り値
- `promise` : Promise オブジェクト
- `resolve` : プロミスの解決関数
- `reject` : プロミスの拒否関数
`Promise.withresolvers` メソッドは以下のコードと全く同じ。
```js
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
```
## 詳細
`Promise.withresolvers` を使用する場合との主な違いは、解決関数や拒否関数を実行環境で一度ずつ作成して使用するのではなく、プロミス自身と同じスコープで使用することである。
これによって、特にストリームやキューで繰り返し発生する [[JavaScriptのイベントとは|イベント]] に使用する場合など、より高度な用途が可能になる。また、一般的に実行環境無いで多くのロジックをラップするよりも入れ子が少なくなる。