在异步函数中使用参数default中的'await'

Max*_*don 3 javascript async-await

我想使用异步函数作为默认参数,但我得到一个错误:'await' is not a valid idientifier name in an async function.这是语言限制还是我错过了什么?

背景

支持以非常简洁的方式使用函数来默认参数:

> a = ({ no }, b = (function(c) { return c -1; })(no)) => console.log(no,b);
[Function: a]
> a({ no: 2 })
2 1
Run Code Online (Sandbox Code Playgroud)

这可以允许从昂贵的数据库调用传递结果,同时保留获取参数的选项(如果为null).这要求我们可以在参数调用中进行等待:

> a = async ({ no }, b = await (async function(c) { return c -1; })(no)) => console.log(no,b);
a = async ({ no }, b = await (async function(c) { return c -1; })(no)) => console.log(no,b);
                       ^^^^^

SyntaxError: 'await' is not a valid identifier name in an async function
Run Code Online (Sandbox Code Playgroud)

我认为这是async/await的一个特性,它是Promises的语法糖,并且重写上面的内容Promise会相当具有挑战性.不过,这个模式真的很整洁,如果我错过了什么,请赐教.

谢谢!

T.J*_*der 7

这是一个限制,特别是在这种情况下AwaitExpression中不允许CoverCallExpressionAndAsyncArrowHead(其包括形式参数).第二个要点是:

  • 如果CoverCallExpressionAndAsyncArrowHead包含AwaitExpression为true ,则为语法错误.

...但是其他各种功能定义都有相同的语言.

我可能不必告诉你,你可以通过不等待异步函数来解决这个问题,直到在体内:

const a = async ({ no }, b = (async function(c) { return c -1; })(no)) => {
// Removed await ------------^
    b = await b; // <== Then added it back within the function body
    console.log(no,b);
};
a({no: 3});
Run Code Online (Sandbox Code Playgroud)


await在默认参数中使用表达式是一个引人入胜的想法.我怀疑它(但是?)允许的原因主要是复杂性管理.(这是我的猜测,用一点点盐.)async函数的开头是同步的(毕竟这是你开始异步操作的方式),它只是变得与第一个awaitreturn(或隐式返回)异步在功能结束时掉下来的那一点).让它在函数体开始之前变为异步会增加一些复杂性.不是说它无法完成.:-)

然而,通过对已解决的问题看的建议,一个问题被提出询问什么时候默认参数初始化抛出一个异常,应该扔掉它或者返回拒绝承诺会发生什么?这引发了TC39的讨论,其中确定它应该返回被拒绝的承诺,因此这个问题的解决方案将参数初始化的评估转移到函数体中(因此异常可能是承诺的一部分).在我看来,似乎开放允许函数await的形式参数的可能性async......