javascript - 在异步函数的参数默认值中使用 'await'

标签 javascript async-await

我想使用异步函数作为默认参数,但出现错误:'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 函数的开头是同步的(毕竟这就是您开始异步操作的方式),它只会变成异步的第一个 awaitreturn (或在函数结束时隐式返回)。让它在函数体开始之前变为异步会增加相当多的复杂性。并不是说它不能 完成。 :-)

但是,查看 the proposal 上已关闭的问题, an issue有人问当默认参数初始化抛出异常时会发生什么,它应该抛出还是返回一个被拒绝的 promise ?这导致了 TC39 讨论,其中确定它应该返回被拒绝的 promise ,因此 this issue ,其解决方案将参数初始化的评估移动到函数体中(因此异常可能是 promise 的一部分)。在我看来,这似乎开启了在 async 函数的形式参数中允许 await 的可能性......

关于javascript - 在异步函数的参数默认值中使用 'await',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49528553/

相关文章:

javascript - 定时器何时从内存中释放

javascript - 在字符串中查找字符串

c# - 如何正确使用异步等待

rust - 轮询许多不同类型的 future

javascript - 你知道 document.createElement ('img' )将完成同步吗?

c# - httpclient async/await 与否

javascript - 等待异步函数的循环

php - 使用 PHP 对网站表格进行排序还是有其他选择?

javascript - 如何将 setTimeout() 与单例模块模式结合使用?

javascript - 我如何提出评级算法/方程式?