await using
å©ç¨å¯è½æ§ã¯éå®ç
ãã®æ©è½ã¯ãã¼ã¹ã©ã¤ã³ã§ã¯ããã¾ãããæãåºã使ç¨ããã¦ãããã©ã¦ã¶ã¼ã®ä¸é¨ã§åä½ãã¾ããã
Want more browser support for this feature? Tell us why.
await using 宣è¨ã¯ãéåæçã«ç ´æ£ããããããã¯ã¹ã³ã¼ãã®ãã¼ã«ã«å¤æ°ã宣è¨ãã¾ãã const ã¨åæ§ã«ã await using ã§å®£è¨ããã夿°ã¯åæåãå¿
è¦ã§ãããå代å
¥ã§ãã¾ããã夿°ã®å¤ã¯ nullãundefinedãã¾ã㯠[Symbol.asyncDispose]() ã [Symbol.dispose]() ã¡ã½ãããæã¤ãªãã¸ã§ã¯ãã®ããããã§ãªããã°ãªãã¾ããã夿°ãã¹ã³ã¼ãå¤ã«ãªãã¨ããªã½ã¼ã¹ãè§£æ¾ããããã«ããªãã¸ã§ã¯ãã® [Symbol.asyncDispose]() ã¾ã㯠[Symbol.dispose]() ã¡ã½ãããå¼ã³åºããå¾
æ©ããã¾ãã
æ§æ
await using name1 = value1;
await using name1 = value1, name2 = value2;
await using name1 = value1, name2 = value2, /* â¦, */ nameN = valueN;
nameN-
宣è¨ãã夿°ã®ååãå夿°åã¯ã JavaScript ã§æå¹ãªèå¥åã§ãªããã°ãªãããæ§é åè§£ãã¤ã³ããã¿ã¼ã³ã§ãã£ã¦ã¯ãªãã¾ããã
valueN-
夿°ã®åæå¤ãæå¹ãªå¼ã§ããã°ä½ã§ãæå®å¯è½ã§ããããã®å¤ã¯
nullãundefinedãã¾ãã¯[Symbol.asyncDispose]()ã[Symbol.dispose]()ã¡ã½ãããæã¤ãªãã¸ã§ã¯ãã®ããããã§ãªããã°ãªãã¾ããã
解説
ãã®å®£è¨ã¯ãawait 㨠using ã®ä¸¡æ¹ã使ç¨å¯è½ãªå ´æã§ã®ã¿ä½¿ç¨ã§ãã¾ããããã«ã¯ä»¥ä¸ã®ãã®ãããã¾ãã
- ãããã¯ã®ä¸ï¼ãããã¯ãéåæã³ã³ããã¹ãã®ä¸ã«ããå ´åï¼
- ä»»æã®éåæé¢æ°ã¾ãã¯éåæã¸ã§ãã¬ã¼ã¿ã¼é¢æ°ã®æ¬ä½ã®ä¸
- ã¢ã¸ã¥ã¼ã«ã®æä¸ä½
forãfor...ofï¼forã«ã¼ããéåæã³ã³ããã¹ãã«ããå ´åï¼ãfor await...ofã«ã¼ãã®åæåå
await using ã¯ã夿°ã®ã¹ã³ã¼ãï¼ãããã¯ã颿°ãã¢ã¸ã¥ã¼ã«ãªã©ï¼ã®åç¶æéã«ç´ã¥ãéåæç ´æ£å¯è½ãªã½ã¼ã¹ã宣è¨ãã¾ããã¹ã³ã¼ããçµäºããã¨ããªã½ã¼ã¹ã¯éåæçã«ç ´æ£ããã¾ãããã®æ§æã¯ããåããã«ããããããã¾ããã ã¨ããã®ãã夿°ãæåã«å®£è¨ãããæç¹ã§ã¯ await ã¯å¾
æ©å¹æãæããã夿°ãã¹ã³ã¼ãå¤ã«åºãæã«ã®ã¿å¹æãçºæ®ããããã§ãã
夿°ãæåã«å®£è¨ããããã®å¤ããã«å¤ã§ãªãå ´åããªãã¸ã§ã¯ããããã£ã¹ãã¼ã¶ã¼ãåå¾ããã¾ããã¾ã [Symbol.asyncDispose] ããããã£ã試è¡ããã[Symbol.asyncDispose] ã undefined ã®å ´å㯠[Symbol.dispose] ã試è¡ããã¾ãããããã®ããããã£ã«ã颿°ãå«ã¾ãã¦ããªãå ´åãTypeError ãçºçãã¾ããç¹çãã¹ãã¯ã[Symbol.dispose]()ã¡ã½ãããasync () => { object[Symbol.dispose](); }ã®ãããªé¢æ°ã«ã©ãããããç¹ã§ããããã¯ãè¿å¤ããããã¹ã§ãã£ã¦ãããã®ãããã¹ãå¾
æ©ãããªããã¨ãæå³ãã¾ãããã®ãã£ã¹ãã¼ã¶ã¼ã¯ã¹ã³ã¼ãã«ä¿åããã¾ãã
夿°ãã¹ã³ã¼ãå¤ã«ãªãã¨ããã£ã¹ãã¼ã¶ã¼ãå¼ã³åºããå¾
æ©ç¶æ
ã«ãªãã¾ããã¹ã³ã¼ãå
ã«è¤æ°ã® using ã¾ã㯠await using 宣è¨ãå«ã¾ããå ´åã宣è¨ã®ç¨®é¡ã«é¢ãããããã¹ã¦ã®ãã£ã¹ãã¼ã¶ã¼ã¯å®£è¨ã®éé ã§é 次å®è¡ããã¾ãããã¹ã¦ã®ãã£ã¹ãã¼ã¶ã¼ã®å®è¡ã¯ä¿è¨¼ããã¾ãï¼try...catch...finally å
ã® finally ãããã¯ã¨åæ§ã§ãï¼ãç ´æ£å¦çä¸ã«çºçããã¨ã©ã¼ã¯ãã¹ã¦ï¼è©²å½ããå ´åãã¹ã³ã¼ãçµäºã®åå ã¨ãªã£ãåæã¨ã©ã¼ãå«ãï¼ã 1 ã¤ã® SuppressedError å
ã«éç´ããã¾ããããããã®å
è¡ããä¾å¤ã¯ suppressed ããããã£ã¨ãã¦ãå¾ç¶ã®ä¾å¤ã¯ error ããããã£ã¨ãã¦ä¿æããã¾ããç ´æ£å¦çå®äºå¾ã«ãã® SuppressedError ãçºçãã¾ãã
ãã®å¤æ°ã¯ null ã¾ã㯠undefined ã®å¤ãåããã¨ã許ãããããããªã½ã¼ã¹ã¯ãªãã·ã§ã³ã¨ãããã¨ãã§ãã¾ãããã®ã¹ã³ã¼ãå
ã§å°ãªãã¨ã 1 ã¤ã® await using 夿°ã宣è¨ããã¦ããã°ã夿°ãå®éã« null ã¾ã㯠undefined ã®å¤ãæã£ã¦ããã¨ãã¦ããã¹ã³ã¼ãçµäºæã«å°ãªãã¨ã 1 ã¤ã® await ãå®è¡ããããã¨ãä¿è¨¼ããã¾ããããã«ãããç ´æ£å¦çãåæçã«çºçãã¦ã¿ã¤ãã³ã°ã®åé¡ãå¼ãèµ·ããã®ãé²ãã¾ãï¼await ã®å¶å¾¡ããã¼ã¸ã®å½±é¿ã«ã¤ãã¦ã¯ await ã®å¶å¾¡ããã¼ã¸ã®å½±é¿ãåç
§ãã¦ãã ããï¼ã
await using ã¯ãªã½ã¼ã¹ç®¡çãåå¥ã¹ã³ã¼ãã«çµã³ä»ãã¾ããããã¯ä¾¿å©ã§ããã¨åæã«ãæã«æ··ä¹±ãæããã¨ãããã¾ããæå¾
éãã«åä½ããªãå¯è½æ§ãããä¾ã以ä¸ã«ç¤ºãã¾ããã¨ã©ã¼å¦çã®ä¿è¨¼ãç¶æãã¤ã¤ãªã½ã¼ã¹ã®ç ´æ£ãæåã§ç®¡çãããå ´åã¯ã代ããã« AsyncDisposableStack ã使ç¨ãããã¨ãã§ãã¾ãã
ä¾
ããå¤ãã®ä¾ã«ã¤ãã¦ã¯ãç¹ã«ã¹ã³ã¼ããã¼ã¹ã®ãªã½ã¼ã¹ç®¡çã«é¢ããä¸è¬çãªæ³¨æç¹ã«ã¤ãã¦ãusing ã確èªãã¦ãã ããã
åºæ¬çãªä½¿ãæ¹
é常ãawait using ã¯ãæ¢ã«éåæç ´æ£å¯è½ãããã³ã«ãå®è£
ãã¦ããã©ã¤ãã©ãªã¼æä¾ã®ãªã½ã¼ã¹ã«å¯¾ãã¦ä½¿ç¨ãã¾ããä¾ãã°ãNode.js ã® FileHandle ã¯éåæç ´æ£å¯è½ã§ãã
import fs from "node:fs/promises";
async function example() {
await using file = await fs.open("example.txt", "r");
console.log(await file.read());
// `file` ãã¹ã³ã¼ãå¤ã«ãªãåã«ã `file[Symbol.asyncDispose]()` ã
// å¼ã³åºãã¦ç ´æ£ãããå¾
æ©ãããã
}
file ã®å®£è¨ã«ã¯ 2 ã¤ã® await æä½ãå«ã¾ãã¦ãããããããç°ãªãå½¹å²ãæããã両æ¹ã¨ãå¿
è¦ã§ãã await fs.open() ã¯å徿ã«å¾
æ©ãè¡ãã¾ãããã¡ã¤ã«ãéãããã®ãå¾
æ©ããè¿ããããããã¹ã FileHandle ãªãã¸ã§ã¯ãã«å±éãã¾ãã await using file ã¯ç ´æ£æã«å¾
æ©ãè¡ãã¾ãã夿°ãã¹ã³ã¼ãå¤ã«åºãéã« file ãéåæçã«ç ´æ£ãã¾ãã
await using ã for await...of ã§ä½¿ç¨
以ä¸ã® 3 ã¤ã®æ§æã¯ã¨ã¦ãæ··ä¹±ããããã§ãã
for await (using x of y) { ... }for (await using x of y) { ... }for (using x of await y) { ... }
ããããä¸ç·ã«ä½¿ãããã¨ãç¥ãã¨ãããã«æ··ä¹±ããããããã¾ããã
for await (await using x of await y) {
// ...
}
ã¾ããawait y ã¯æå¾
ã©ããã«åä½ãã¾ãããããã¹ y ã await ãã¾ãããã®ãããã¹ã¯è§£æ±ºæã«ãªãã¸ã§ã¯ããè¿ãã¨äºæ³ããããã®ãªãã¸ã§ã¯ããå復å¦çãã¾ãããã®ããªã¨ã¼ã·ã§ã³ã¯ã²ã¨ã¾ãèã«ç½®ãã¦ããã¾ãããã
for await...of ã«ã¼ãã§ã¯ã y ãªãã¸ã§ã¯ããéåæå復å¯è½ãªãã¸ã§ã¯ãã§ããå¿
è¦ãããã¾ããããã¯ããªãã¸ã§ã¯ãã [Symbol.asyncIterator] ã¡ã½ãããæã¡ããã®ã¡ã½ãããéåæã¤ãã¬ã¼ã¿ã¼ãè¿ãããã® next() ã¡ã½ãããçµæã表ããããã¹ãè¿ãã¨ãããã¨ã§ããããã¯ãå復å¯è½ãªãã¸ã§ã¯ããæ¬¡ã®å¤ãä½ã§ãããããããã¯éåææä½ãå®äºããã¾ã§å¦çãçµäºãããã©ãããããããã®æä½ãå®äºããã¾ã§ç¥ããªãå ´åã«åãããã®ã§ãã
䏿¹ã await using x æ§æã§ã¯ãå復å¯è½ãªãã¸ã§ã¯ããã yield ããã x ãªãã¸ã§ã¯ããéåæãã£ã¹ãã¼ã¶ã¼ã§ããå¿
è¦ãããã¾ããããã¯ããªãã¸ã§ã¯ããç ´æ£æä½ã表ããããã¹ãè¿ã [Symbol.asyncDispose] ã¡ã½ãããæã¤å¿
è¦ãããã¨ãããã¨ã§ããããã¯å復å¦çèªä½ã¨ã¯å¥ã®åé¡ã§ããã夿° x ãã¹ã³ã¼ãå¤ã«åºãã¨ãã«ã®ã¿å¼ã³åºããã¾ãã
è¨ãæããã°ã以ä¸ã® 4 ã¤ã®çµã¿åããã¯ãã¹ã¦æå¹ã§ãããããããç°ãªãåä½ããã¾ãã
for (using x of y):yã¯åæçã«å復å¦çãããä¸åº¦ã« 1 ã¤ã®çµæãè¿ãã¾ãããã®çµæã¯åæçã«ç ´æ£ã§ãã¾ããfor await (using x of y):yã¯éåæã«å復å¦çãããå¾ æ©å¾ã«ä¸åº¦ã« 1 ã¤ã®çµæãè¿ãã¾ãããçµæã®å¤ã¯åæçã«ç ´æ£ã§ãã¾ããfor (await using x of y):yã¯åæçã«å復å¦çãããä¸åº¦ã« 1 ã¤ã®çµæãè¿ãã¾ãããçµæã®å¤ã¯éåæçã«ã®ã¿ç ´æ£ããã¾ããfor await (await using x of y):yã¯éåæã«å復å¦çãããå¾ æ©å¾ã«ä¸åº¦ã« 1 ã¤ã®çµæãè¿ãã¾ããçµæã®å¤ã¯éåæã«ã®ã¿ç ´æ£ããã¾ãã
以ä¸ã§ã¯ã y ã®æ¶ç©ºã®å¤ãããã¤ã使ãããã®ä½¿ç¨å¯è½ãªå ´åã示ãã¾ããéåæ API ã«ã¤ãã¦ã¯ã Node.js ã® fs/promises ã¢ã¸ã¥ã¼ã«ãåºã«ã³ã¼ããå®è£
ãã¾ãã
const syncIterableOfSyncDisposables = [
stream1.getReader(),
stream2.getReader(),
];
for (using reader of syncIterableOfSyncDisposables) {
console.log(reader.read());
}
async function* requestMany(urls) {
for (const url of urls) {
const res = await fetch(url);
yield res.body.getReader();
}
}
const asyncIterableOfSyncDisposables = requestMany([
"https://example.com",
"https://example.org",
]);
for await (using reader of asyncIterableOfSyncDisposables) {
console.log(reader.read());
}
const syncIterableOfAsyncDisposables = await Promise.all(
fs.globSync("*.txt").map((path) => fs.open(path, "r")),
);
for (await using file of syncIterableOfAsyncDisposables) {
console.log(await file.read());
}
async function* globHandles(pattern) {
for await (const path of fs.glob(pattern)) {
yield await fs.open(path, "r");
}
}
const asyncIterableOfAsyncDisposables = globHandles("*.txt");
for await (await using file of asyncIterableOfAsyncDisposables) {
console.log(await file.read());
}
ã¹ã³ã¼ãçµäºæã®æé»ã®å¾ æ©
ã¹ã³ã¼ãå
ã§ await using ã宣è¨ãããã¨ã夿°ã null ã¾ã㯠undefined ã§ãã£ã¦ãããã®ã¹ã³ã¼ãã¯çµäºæã«å¸¸ã« await ãå®è¡ãã¾ããããã«ããå®å®ããå®è¡é åºã¨ã¨ã©ã¼å¦çãä¿è¨¼ããã¾ãã詳細ã«ã¤ãã¦ã¯ã await ã®å¶å¾¡ããã¼ã¸ã®å½±é¿ã®ä¾ãåç
§ãã¦ãã ããã
以ä¸ã®ä¾ã§ã¯ã颿°ãè¿ãéã«æé»ã® await ãçºçãããããexample() ã®å¼ã³åºãã¯æ¬¡ã®ãã£ãã¯ã¾ã§è§£æ±ºããã¾ããã
async function example() {
await using nothing = null;
console.log("Example call");
}
example().then(() => console.log("Example done"));
Promise.resolve().then(() => console.log("Microtask done"));
// åºå:
// Example call
// Microtask done
// Example done
åãã³ã¼ããã代ããã«åæç㪠using ã使ç¨ããå ´åãèãã¦ã¿ã¾ããããä»å㯠example() ã®å¼ã³åºããå³åº§ã«è§£æ±ºãããããã2ã¤ã® then() ãã³ãã©ã¼ã¯åããã£ãã¯å
ã§å¼ã³åºããã¾ãã
async function example() {
using nothing = null;
console.log("Example call");
}
example().then(() => console.log("Example done"));
Promise.resolve().then(() => console.log("Microtask done"));
// åºåçµæ:
// Example call
// Example done
// Microtask done
ããç¾å®çãªä¾ã¨ãã¦ã颿°ã¸ã® 2 ã¤ã®åæå¼ã³åºããèãã¦ã¿ã¾ãããã
class Resource {
#name;
constructor(name) {
this.#name = name;
}
async [Symbol.asyncDispose]() {
console.log(`Disposing resource ${this.#name}`);
}
}
async function example(id, createOptionalResource) {
await using required = new Resource(`required ${id}`);
await using optional = createOptionalResource
? new Resource("optional")
: null;
await using another = new Resource(`another ${id}`);
}
example(1, true);
example(2, false);
// åºåçµæ:
// Disposing resource another 1
// Disposing resource another 2
// Disposing resource optional
// Disposing resource required 1
// Disposing resource required 2
ã覧ã®éãã required 2 ãªã½ã¼ã¹ã¯ required 1 ã¨åããã£ãã¯ã§ç ´æ£ããã¾ãããã optional ãªã½ã¼ã¹ãåé·ãª await ãè¡ããªããã°ã required 2 ã¯ããæ©ãç ´æ£ããã optional ã¨åæã«ç ´æ£ããã¦ããã§ãããã
仿§æ¸
| 仿§æ¸ |
|---|
| ECMAScript Async Explicit Resource Management > # prod-AwaitUsingDeclaration > |