为什么此异步生成器会导致JavaScript运行时挂起?

时间:2020-02-23 19:12:09

标签: javascript

以下JavaScript导致运行时在OSX 10.15.2上的Chrome(v80.0.3987.116)和Firefox(v72.0.2)上挂起。

为什么?

请注意,我将迭代器功能标记为async

const iterable = {
    async *[Symbol.iterator]() {
        yield 'one'
    }
}

console.log([...iterable])

2 个答案:

答案 0 :(得分:4)

因为现在您的[Symbol.iterator]方法不再返回Iterator,所以它确实返回了AsyncIterator。那仍然是带有.next()方法的对象,因此尝试对其进行迭代的散布语法不会抱怨。但是,对.next()方法的调用不再返回{value:…, done:true}对象,它们总是返回一个promise。这些promise对象没有真实的done属性,因此您的迭代器永远不会停止……

您可以通过

获得相同的结果
const iterable = {
    *[Symbol.iterator]() {
        while (true) {
            yield
        }
    }
}    
console.log([...iterable])

const iterable = {
    [Symbol.iterator]() {
        return {
            next() {
                return {};
            }
        }
    }
}
console.log([...iterable])

答案 1 :(得分:3)

调用console.log([...iterable])时,它告诉Javascript从Symbol.iterator的{​​{1}}属性获取生成器以对其进行迭代。其中iterableSymbol.iterator(因为前面有AsyncGenerator),而不是常规的async。这意味着来自该生成器的Generator函数将返回next,但不会返回具有Promisedone值的对象。因此,js将返回的value用作Promise的属性,以done停止迭代,但是返回的true没有此属性,因此检查失败并js使迭代继续进行。

可以通过以下方式获得相同的结果:

Promise

希望对您有帮助<3