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

时间:2018-03-28 07:30:04

标签: 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

这可以允许从昂贵的数据库调用传递结果,同时保留获取参数的选项(如果为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会相当具有挑战性。不过,这个模式真的很整洁,如果我错过了什么,请赐教。

谢谢!

1 个答案:

答案 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;
&#13;
&#13;

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

然而,查看the proposal上已关闭的问题,提出了an issue,询问当默认参数初始化引发异常时会发生什么,如果抛出或返回拒绝诺言?这引发了TC39讨论,其中确定它应该返回被拒绝的承诺,因此this issue,其解决方案将参数初始化的评估移动到函数体中(因此异常可能是承诺的一部分) 。在我看来,似乎可以在await函数的形式参数中允许async ...