Pat*_*rts 5 javascript syntax generator language-lawyer ecmascript-2018
在编写异步生成器函数时,我注意到以下构造会产生SyntaxError:
async function * foo() {
await yield bar; // Can not use 'yield' as identifier inside a generator
}
Run Code Online (Sandbox Code Playgroud)
尽管颠倒上下文关键字的顺序是完全可以接受的:
async function * foo() {
yield await bar; // OK
}
Run Code Online (Sandbox Code Playgroud)
仔细阅读错误后,我能够通过将 括在括号UnaryExpression内来纠正语法AwaitExpression,以避免将令牌解析yield为标识符而不是上下文关键字:
async function * foo() {
await (yield bar); // OK
}
Run Code Online (Sandbox Code Playgroud)
但这引出了一个问题,ECMAScript 2018中涉及哪些特定的静态语义,导致yield在这种情况下被解析为标识符,同时await不需要特殊处理?
这是一个运算符的优先级await问题,它形成 aUnaryExpression(并以 1 作为其操作数),与形成 anyield (并以 1 作为其可选操作数)的运算符不同。An不形成 a ,这意味着您根本不允许像这样嵌套它们。AssignmentExpressionAssignmentExpressionUnaryExpression
解析表达式时await,提供给解析的下一个标记用于形成 a ,而执行此操作UnaryExpression的唯一选择是作为 an (完全忽略其后面的)。当然,在生成器解析上下文中这是不允许的,会导致令人困惑的错误消息。yieldIdentifierReferencebar
请注意,无论如何,两种形式的嵌套 (await (yield \xe2\x80\xa6)和yield (await \xe2\x80\xa6)) 都是完全不必要的,因为异步生成器函数中的关键字已经在内部yield等待生成值和恢复值,因此您应该省略关键字并仅使用.awaityield