pep*_*dip 21 javascript async-await eslint
有什么区别
return await foo()
Run Code Online (Sandbox Code Playgroud)
和
const t = await foo();
return t
Run Code Online (Sandbox Code Playgroud)
sam*_*ime 27
基本上,因为return await是多余的.
从实际使用async函数的稍高级别来看它:
const myFunc = async () => {
return await doSomething();
};
await myFunc();
Run Code Online (Sandbox Code Playgroud)
任何async函数都已经返回a Promise,并且必须作为a处理Promise(直接作为a Promise或者也作为await-ing).
如果你await在函数内部,它是多余的,因为外面的函数也会await以某种方式,所以没有理由不发送它Promise,让外面的东西处理它.
它在语法上不对错或不正确,通常不会引起问题.这完全是多余的,这就是为什么linter触发它.
Bam*_*ieh 11
它在规则的前几行中描述:
在异步函数内,返回await是没用的.由于异步函数的返回值始终包含在Promise.resolve中,因此除了在总体Promise解析或拒绝之前添加额外时间之外,返回await实际上并不执行任何操作.这种模式几乎可以肯定是由于程序员忽略了异步函数的返回语义.资源
基本上返回或不返回,将导致相同的事情,因为await将解决promise,因此不需要返回已解析的状态.
和...之间的不同:
async function foo() {
return bar();
}
async function bar() {
await Promise.resolve();
throw new Error('BEEP BEEP');
}
foo().catch(error => console.log(error.stack));
Error: BEEP BEEP
at bar (<anonymous>:7:9)
Run Code Online (Sandbox Code Playgroud)
和
async function foo() {
return await bar();
}
Error: BEEP BEEP
at bar (<anonymous>:7:9)
at async foo (<anonymous>:2:10)
Run Code Online (Sandbox Code Playgroud)
最终结果是相同的,尽管将值保存到变量中并且之后立即返回它是不是最好的想法(您向引擎添加额外的步骤:保存到变量,然后获取该变量的值引用,返回它,它还可以防止像某些情况下的尾调用优化等.
因为你没有使用指定的变量,所以不要分配它.
现在回到为什么linter在这种情况下没有错误:
例如:
async function foo() {
return bar();
}
async function bar() {
await Promise.resolve();
throw new Error('BEEP BEEP');
}
foo().catch(error => console.log(error.stack));
Error: BEEP BEEP
at bar (<anonymous>:7:9)
Run Code Online (Sandbox Code Playgroud)
要么
async function foo() {
return await bar();
}
Error: BEEP BEEP
at bar (<anonymous>:7:9)
at async foo (<anonymous>:2:10)
Run Code Online (Sandbox Code Playgroud)
Tam*_*dus 11
更新:该no-return-await规则自 以来已弃用v8.46.0。世界正在康复。
这里许多人建议省略等待和写入return foo();,但这是一个明显错误的建议。写作没有什么问题return await foo();;相反,省略await是代码中的一个错误,我将在下面解释。因此,请关闭该no-return-await规则,正如 ESLint 和 SonarCloud 团队同时意识到的那样,并弃用了它。
省略await会破坏try-catch块,导致finally块过早运行,并导致异步堆栈跟踪中丢失一些行。也会断裂explicit resource management。在我看来,跳过await是一种误导性的尝试,旨在实现某种毫无根据的“优化”的抽象意义,以代码为代价节省 6 个字符和一个微任务(编辑:ShortFuse 只是表明它实际上不是保存,而是在当前 v8 中添加了一个微任务)正确性。经验法则很简单:如果您有异步调用,请等待它,即使在 return 语句中也是如此。让我们坚持经验法则并始终使用return await,并关闭no-return-awaiteslint 规则。
现在是咆哮:我花了多少天时间向开发人员解释,他们认为自己catch在块没有运行时发现了 V8 错误,以及我花了多少长时间争论试图包装 V8 的拉取请求。 try 块中的异步函数体,但不添加那些缺少的等待。因此,我们发生了多起生产事故。我的开发人员不断指出该no-return-await规则,当我对其提出质疑时,他们在堆栈溢出上指出了这些具有 100K 秒声誉的答案,并表示“但是等待是多余的!不能等待!”。我更改了我们的规则集,添加和链接了文档,但开发人员往往相信更高的权威,所以我不得不与他们坐下来,一起运行这些示例,让他们相信这不是节点错误,你只需要等待。我每个季度都必须与每个新开发人员一起做这件事。这是一场职业噩梦,让 70 名高级开发人员相信他们的基本假设一直都是错误的。我不能责怪他们,因为他们依赖“信誉良好的消息来源”。所以我们需要在我们行业的核心解决这个问题,我很感激 ESLint 改变了方向。如果我们从一开始就务实地坚持始终return await asyncFoo();,我们今天就不会遇到任何这些问题,而且我还可以节省数百个工程时间和更多的理智。
小演示,显示堆栈跟踪中缺失的行,并演示了过早运行的finally块:
async function main() {
console.log("\nStatcktrace with await shows testStackWithAwait:");
await testStackWithAwait().catch(logStack);
console.log("\nStatcktrace without await shows missing testStackWithoutAwait:");
await testStackWithoutAwait().catch(logStack);
console.log("\nFinally runs before try block ends when await is omitted:");
await testFinallyWithoutAwait();
}
async function fnThatThrows() {
await delay(1);
throw new Error();
}
async function testStackWithoutAwait() {
return fnThatThrows(); // bad
}
async function testStackWithAwait() {
return await fnThatThrows(); // good
}
async function fnThatLogs() {
await delay(1);
console.log(' Running in try block');
}
async function testFinallyWithoutAwait() {
try {
return fnThatLogs(); // bad
} finally {
console.log(' Running in finally block');
}
}
function logStack(e) {
console.log(e.stack);
}
function delay(timeout, value) {
return new Promise(resolve => {
setTimeout(() => {
resolve(value);
}, timeout);
});
}
main().catch(console.error);Run Code Online (Sandbox Code Playgroud)
在 Windows 上的 Chrome 103 和 120 上,我收到以下日志:
Statcktrace with await shows testStackWithAwait:
Error
at fnThatThrows (https://stacksnippets.net/js:23:9)
at async testStackWithAwait (https://stacksnippets.net/js:31:10)
at async main (https://stacksnippets.net/js:14:3)
Statcktrace without await shows missing testStackWithoutAwait:
Error
at fnThatThrows (https://stacksnippets.net/js:23:9)
at async main (https://stacksnippets.net/js:16:3)
Finally runs before try block ends when await is omitted:
Running in finally block
Running in try block
Run Code Online (Sandbox Code Playgroud)
因为你可以
async function() {
return foo();
}
Run Code Online (Sandbox Code Playgroud)
无论您返回的是精确值还是函数体内的另一个对象,async function始终返回的结果是PromisePromise
| 归档时间: |
|
| 查看次数: |
8105 次 |
| 最近记录: |