🔆

Chrome 134 がリリースされたのに誰も using /await using の話をしないので

2025/03/06に公開

Chrome 134 がリリースされましたね。

https://developer.chrome.com/blog/new-in-chrome-134?hl=ja

https://developer.chrome.com/release-notes/134?hl=ja

ちなみに今回の 134 には 現在策定中の proposal の ECMAScript Explicit Resource Management(日本語訳だと 明示的なリソースの管理) の実装が含まれています。 現在(2025/03/06) stage 3 のプロポーザルで実装待ちの段階です(実装が2つ完了すると stage 4 になります。

今回のリリースノートも 新機能の記事も explicit resource management の話が出ていないのでとりあえず記事にしました。

chrome status だと以下のページが参考となります。

https://chromestatus.com/feature/5071680358842368

https://chromestatus.com/feature/5087324181102592

仕様としては以下の github と ページが参考になります。

https://github.com/tc39/proposal-explicit-resource-management

https://tc39.es/proposal-explicit-resource-management/

このプロポーザルは 現在ある ブロックスコープの変数宣言である letconst 以外の using および await using を追加するものです。
その値は using の場合は Symbol.dispose に同期メソッドを、await using の場合は Symbol.asyncDispose に非同期メソッドを実装する必要があり、それぞれそのブロックスコープを抜ける際にそれぞれの関数が実行されるという仕様となります。 実行タイミングのニュアンスは try finally なので必ず解放する必要がある リソース系の処理に使うことが考えられているものです。

コードで書くとこんな感じのコードができます

console.log('0');
{
   console.log('1');
   using v = { [Symbol.dispose]: () => console.log('3'), };
   console.log('2');
}
console.log('4');
console.log('0');
{
   console.log('1');
   await using v = { [Symbol.asyncDispose]: async () => console.log('3'), };
   console.log('2');
}
console.log('4');

実行順は 登録した逆順で解放されます。

console.log('0');
{
   console.log('1');
   // let や const と同じで , で複数書ける
   using v1 = { [Symbol.dispose]: () => console.log('6'), },
         v2 = { [Symbol.dispose]: () => console.log('5'), };
   console.log('2');
   await using v3 = { [Symbol.asyncDispose]: async () => console.log('4'), };
   console.log('3');
}
console.log('7');

AsyncDisposeStack に登録してまぜこぜで登録するのも手です。

console.log('0');
{
   console.log('1');
   await using stack = new AsyncDisposableStack();
   // let や const と同じで , で複数書ける
   stack.use({ [Symbol.dispose]: () => console.log('7'), });
   stack.use({ [Symbol.asyncDispose]: async () => console.log('6'), });
   console.log('2');
   stack.use({ 
       [Symbol.dispose]: () => console.log('not call'),
       [Symbol.asyncDispose]: async () => console.log('5'),
   });
   console.log('3');
   // コールバックも 同期 / 非同期 ともに登録できる
   stack.defer(() => console.log('4'));
}
console.log('8');

私としては addEventListener の戻り値に設定して using したいな感があるのではありますが………。

動作するか確認するなら次の様なコードですね。

追伸: リリースノートの方にありました

明示的なリソース管理(非同期)

これらの機能は、さまざまなリソース(メモリや I/O など)の存続期間と管理に関するソフトウェア開発の一般的なパターンに対応しています。このパターンには通常、リソースの割り当てと、重要なリソースを明示的に解放する機能が含まれます。
バグのトラッキング #42203814 | ChromeStatus.com のエントリ | 仕様

明示的なリソース管理(同期)

これらの機能は、さまざまなリソース(メモリや I/O など)の存続期間と管理に関するソフトウェア開発の一般的なパターンに対応しています。このパターンには通常、リソースの割り当てと、重要なリソースを明示的に解放する機能が含まれます。
バグのトラッキング #42203506 | ChromeStatus.com のエントリ | 仕様

https://developer.chrome.com/release-notes/134?hl=ja#explicit_resource_management_async

追伸の追伸: Microsoft Edge のリリースノートにも来てる

2025/03/06 の週 にリリース予定の MicrosoftEdge 134 のリリースノートにも記載があることを確認。

明示的なリソース管理
この機能では、JavaScript にusing キーワード (keyword)が導入され、開発者はリソースを明示的に管理できます。 using キーワード (keyword)は、リソースを使用するコード ブロックを定義するために使用され、ブロックが終了したときにリソースが破棄されるようにします。 この機能は、さまざまなリソース (メモリや I/O など) の有効期間と管理に関するソフトウェア開発の一般的なパターンに対処します。 このパターンでは、リソースの割り当てと重要なリソースの明示的な解放がサポートされます。

ECMAScript の明示的なリソース管理に関するページを参照してください。

https://learn.microsoft.com/ja-jp/microsoft-edge/web-platform/release-notes/134#explicit-resource-management

Discussion