无法在生成器内部使用“ yield”作为标识符

时间:2019-12-10 17:08:44

标签: javascript syntax language-lawyer generator ecmascript-2018

在编写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不需要特殊处理?

1 个答案:

答案 0 :(得分:2)

这是precedence of the await operator的问题,其中forms a UnaryExpression(并有一个作为其操作数),而yield运算符有forms an AssignmentExpression(有一个作为其可选操作数) )。 AssignmentExpression不会形成UnaryExpression,这意味着根本不允许您像这样嵌套它们。

解析await表达式时,馈入解析的下一个标记用于形成UnaryExpressionyield要做的唯一选择是{{ 1}}(完全忽略其后的IdentifierReference)。当然,在不允许的生成器解析上下文中,会导致混乱的错误消息。

请注意,两种形式的嵌套(barawait (yield …)都是完全不必要的,因为异步生成器函数中的yield (await …)关键字已经在等待产生的值和恢复值internally,因此您只需忽略yield关键字,而仅使用await