不能在生成器中使用 'yield' 作为标识符

Can not use 'yield' as identifier inside a generator

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

这是 , which forms a UnaryExpression (and has one as its operand), unlike the yield operator which forms an AssignmentExpression 的问题(并且有一个作为其可选操作数)。 AssignmentExpression 不会形成 UnaryExpression,这意味着您根本不允许这样嵌套它们。

解析 await 表达式时,将使用下一个提供给解析的标记来形成 UnaryExpression,而 yield 唯一的选择是作为一个IdentifierReference(完全忽略紧随其后的 bar)。当然在不允许的生成器解析上下文中,会导致令人困惑的错误消息。

请注意,两种形式的嵌套(await (yield …)yield (await …))无论如何都是完全不必要的,因为异步生成器函数中的 yield 关键字已经等待产生的值和恢复值 internally,因此您应该省略 await 关键字并仅使用 yield.