The following JavaScript causes the runtime to hang on Chrome (v80.0.3987.116) and Firefox (v72.0.2) on OSX 10.15.2.
Why?
Note that I am marking the iterator function as async
.
const iterable = {
async *[Symbol.iterator]() {
yield 'one'
}
}
console.log([...iterable])
Because now your [Symbol.iterator]
method no longer returns an Iterator, it does return an AsyncIterator. That's still an object with a .next()
method, so the spread syntax trying to iterate it doesn't complain. But the calls to the .next()
method do no longer return {value:…, done:true}
objects, they always return a promise. These promise objects have no truthy done
property, so your iterator never stops…
You can achieve the same result with
const iterable = {
*[Symbol.iterator]() {
while (true) {
yield
}
}
}
console.log([...iterable])
or
const iterable = {
[Symbol.iterator]() {
return {
next() {
return {};
}
}
}
}
console.log([...iterable])
When you call console.log([...iterable])
, it tells Javascript to get a generator from Symbol.iterator
property on iterable
to iterate over it. Where, Symbol.iterator
is AsyncGenerator
(because of async
in front of it), rather not a regular Generator
. Meaning that next
function from that generator returns a Promise
, but not an object with done
and value
values. So, js takes that returned Promise
and looks for done
property to be true
to stop iteration, but returned Promise
doesn't have this property, so the check fails and js keeps the iterations going.
The same result can be achieved in this way:
const iterable = {
[Symbol.iterator]() {
return {
next() {
return {} // <~ doesn't have done property - will cause infinite iteration
}
}
}
}
console.log([...iterable])
Hope it helps <3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With