我想使用异步函数作为默认参数,但出现错误:'await' 不是异步函数中的有效标识符名称
。这是语言限制还是我错过了什么?
背景
支持以非常简洁的方式使用函数来默认参数:
> 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
会相当具有挑战性。不过,该模式会非常整洁,如果我遗漏了什么,请赐教。
谢谢!
最佳答案
这是一个限制,特别是在这种情况下 AwaitExpression is not allowed in CoverCallExpressionAndAsyncArrowHead (其中包括形式参数)。第二个要点是:
- It is a Syntax Error if CoverCallExpressionAndAsyncArrowHead Contains AwaitExpression is 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});
在默认参数中使用 await
表达式是一个有趣的想法。我怀疑它不(还?)被允许的原因主要是复杂性管理。 (这只是我的猜测,请稍加保留。)async
函数的开头是同步的(毕竟这就是您开始异步操作的方式),它只会变成异步的第一个 await
或 return
(或在函数结束时隐式返回)。让它在函数体开始之前变为异步会增加相当多的复杂性。并不是说它不能 完成。 :-)
但是,查看 the proposal 上已关闭的问题, an issue有人问当默认参数初始化抛出异常时会发生什么,它应该抛出还是返回一个被拒绝的 promise ?这导致了 TC39 讨论,其中确定它应该返回被拒绝的 promise ,因此 this issue ,其解决方案将参数初始化的评估移动到函数体中(因此异常可能是 promise 的一部分)。在我看来,这似乎开启了在 async
函数的形式参数中允许 await
的可能性......
关于javascript - 在异步函数的参数默认值中使用 'await',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49528553/