for await of と asyncIterator
- カテゴリ:
- JavaScript
- コメント数:
- Comments: 0
◆ for-await-of は Symbol.asyncIterator を見てる
◆ なければ Symbol.iterator
◆ なければ Symbol.iterator
for await of って全然使ってなくて わざわざ構文にしなくても中で await すればいいじゃんと思ってました
一つ変数は減り 見やすいのはたしかですがそれだけのために構文追加ってやりすぎ感があります
ですが それだけではなかったです
Symbol.asyncIterator が未定義なら Symbol.iterator を使います
逆の Symbol.iterator が未定義で Symbol.asyncIterator がある場合は for-await-of では問題なく動きますが for-of は動きません
obj is not iterable というエラーになります
単純に中で await するだけならわざわざ作る意味あったのかと思いましたが 見るシンボルが変わるのなら使い分けもできそうですし 有効な使いみちがあるような気もします
ちなみに AsyncGenerator のインスタンスは asyncIterator のみなので通常の for-of は使えません
function* gen(urls) {
for (const url of urls) {
yield fetch(url)
}
}
const urls = [
"https://www.google.com/",
"https://www.amazon.com/",
"https://github.com/",
]
for await (const res of gen(urls)) {
console.log(Date.now() % 10000, res.status, res.url)
}
for (const p of gen(urls)) {
const res = await p
console.log(Date.now() % 10000, res.status, res.url)
}
5381 200 "https://www.google.com/"
6083 200 "https://www.amazon.com/"
6907 200 "https://github.com/"
7037 200 "https://www.google.com/"
7268 200 "https://www.amazon.com/"
7946 200 "https://github.com/"
一つ変数は減り 見やすいのはたしかですがそれだけのために構文追加ってやりすぎ感があります
ですが それだけではなかったです
asyncIterator
for-of 文では Symbol.iterator を見ますが for-await-of では Symbol.asyncIterator というまた別のものをみていましたconst obj = {}
obj[Symbol.iterator] = function*() { yield* [1, 2, 3] }
obj[Symbol.asyncIterator] = function*() { yield* [100, 200, 300] }
for (const v of obj) console.log(v)
for await (const v of obj) console.log(v)
1
2
3
100
200
300
Symbol.asyncIterator が未定義なら Symbol.iterator を使います
const obj = {}
obj[Symbol.iterator] = function*() { yield* [1, 2, 3] }
obj[Symbol.asyncIterator] = null
for (const v of obj) console.log(v)
for await (const v of obj) console.log(v)
1
2
3
1
2
3
逆の Symbol.iterator が未定義で Symbol.asyncIterator がある場合は for-await-of では問題なく動きますが for-of は動きません
obj is not iterable というエラーになります
単純に中で await するだけならわざわざ作る意味あったのかと思いましたが 見るシンボルが変わるのなら使い分けもできそうですし 有効な使いみちがあるような気もします
ちなみに AsyncGenerator のインスタンスは asyncIterator のみなので通常の for-of は使えません
const ai = async function*(){}()
ai[Symbol.iterator]
// undefined
ai[Symbol.asyncIterator]
// ƒ [Symbol.asyncIterator]() { [native code] }