在编写async generator函数时,我注意到以下构造会生成SyntaxError
:
async function * foo() {
await yield bar; // Can not use 'yield' as identifier inside a generator
}
即使颠倒上下文关键字的顺序也是完全可以接受的:
async function * foo() {
yield await bar; // OK
}
仔细阅读错误后,我可以通过将UnaryExpression
括在括号内的AwaitExpression
中来纠正语法,从而避免将标记yield
解析为标识符而不是上下文关键字:
async function * foo() {
await (yield bar); // OK
}
但这引出了一个问题,ECMAScript 2018中涉及到哪些特定的静态语义导致yield
在此上下文中被解析为标识符,而await
不需要特殊处理?
答案 0 :(得分:2)
这是precedence of the await
operator的问题,其中forms a UnaryExpression
(并有一个作为其操作数),而yield
运算符有forms an AssignmentExpression
(有一个作为其可选操作数) )。 AssignmentExpression
不会形成UnaryExpression
,这意味着根本不允许您像这样嵌套它们。
解析await
表达式时,馈入解析的下一个标记用于形成UnaryExpression
,yield
要做的唯一选择是{{ 1}}(完全忽略其后的IdentifierReference
)。当然,在不允许的生成器解析上下文中,会导致混乱的错误消息。
请注意,两种形式的嵌套(bar
和await (yield …)
都是完全不必要的,因为异步生成器函数中的yield (await …)
关键字已经在等待产生的值和恢复值internally,因此您只需忽略yield
关键字,而仅使用await
。