我想使用异步函数作为默认参数,但我收到错误:'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
这可以允许从昂贵的数据库调用传递结果,同时保留获取参数的选项(如果为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
我认为这是async / await的一个特性,它是Promises的语法糖,并重写上面的Promise
会相当具有挑战性。不过,这个模式真的很整洁,如果我错过了什么,请赐教。
谢谢!
答案 0 :(得分:7)
这是一个限制,特别是在这种情况下AwaitExpression is not allowed in CoverCallExpressionAndAsyncArrowHead(包括形式参数)。第二个要点是:
- 如果 CoverCallExpressionAndAsyncArrowHead 包含 AwaitExpression 为真,则语法错误。
...但是其他各种函数定义都有相同的语言。
我可能不必告诉你,你可以通过不等待异步函数来解决这个问题,直到在体内:
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});
&#13;
在默认参数中使用await
表达式是一个引人入胜的想法。我怀疑它(但是?)允许的原因主要是复杂性管理。 (这是我的猜测,用一点点盐就可以了。)async
函数的开头是同步的(毕竟这是你开始异步操作的方式),它只是异步从第一个await
或return
开始(或者在函数结束时隐式返回)。让它在函数体开始之前变为异步会增加一些复杂性。不是说无法完成 。 : - )
然而,查看the proposal上已关闭的问题,提出了an issue,询问当默认参数初始化引发异常时会发生什么,如果抛出或返回拒绝诺言?这引发了TC39讨论,其中确定它应该返回被拒绝的承诺,因此this issue,其解决方案将参数初始化的评估移动到函数体中(因此异常可能是承诺的一部分) 。在我看来,似乎可以在await
函数的形式参数中允许async
...