[英]Why no-return-await vs const x = await?
What is the difference between和有什么区别
return await foo()
and和
const t = await foo();
return t
http://eslint.org/docs/rules/no-return-await http://eslint.org/docs/rules/no-return-await
Basically, because return await
is redundant.基本上,因为
return await
是多余的。
Look at it from a slightly higher level of how you actually use an async
function:从你实际如何使用
async
函数的更高层次来看它:
const myFunc = async () => {
return await doSomething();
};
await myFunc();
Any async
function is already going to return a Promise
, and must be dealt with as a Promise
(either directly as a Promise
, or by also await
-ing.任何
async
函数都将返回一个Promise
,并且必须作为Promise
处理(直接作为Promise
,或者也通过await
-ing。
If you await
inside of the function, it's redundant because the function outside will also await
it in some way, so there is no reason to not just send the Promise
along and let the outer thing deal with it.如果你在函数内部
await
,它是多余的,因为外部的函数也会以某种方式await
它,所以没有理由不只是发送Promise
并让外部处理它。
It's not syntactically wrong or incorrect and it generally won't cause issues.它在语法上没有错误或不正确,通常不会引起问题。 It's just entirely redundant which is why the linter triggers on it.
这完全是多余的,这就是 linter 触发它的原因。
Using return await
does have some newly introduced benefits in v8 engine used by Node.js, Chrome and a few other browsers:在 Node.js、Chrome 和其他一些浏览器使用的 v8 引擎中,使用
return await
确实有一些新引入的好处:
v8 introduced a --async-stack-traces
flag which as of V8 v7.3 is enabled by default (Node.js v12.0.0). v8 引入了一个
--async-stack-traces
标志,从 V8 v7.3 开始默认启用(Node.js v12.0.0)。
This flags provides an improved developer experience by enriching the Error stack property with async function calls stack trace.此标志通过使用异步函数调用堆栈跟踪丰富错误堆栈属性来提供改进的开发人员体验。
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)
Note that by calling return bar();
请注意,通过调用
return bar();
foo()
function call does not appear at all in the error stack. foo()
函数调用根本不会出现在错误堆栈中。 Changing it to return await bar();
将其更改为
return await bar();
gives a much better error stack output:提供更好的错误堆栈输出:
async function foo() {
return await bar();
}
foo();
Error: BEEP BEEP
at bar (<anonymous>:7:9)
at async foo (<anonymous>:2:10)
This indeed does provide much better error stack tracing, hence it is HIGHLY encouraged to always await your promises.这确实提供了更好的错误堆栈跟踪,因此强烈建议始终等待您的承诺。
Additionally, async/wait now outperformes hand written promises:此外,async/wait 现在优于手写承诺:
async/await
outperforms hand-written promise code now.async/await
现在优于手写的 Promise 代码。 The key takeaway here is that we significantly reduced the overhead of async functions — not just in V8, but across all JavaScript engines, by patching the spec.这里的关键点是,我们通过修补规范显着降低了异步函数的开销——不仅在 V8 中,而且在所有 JavaScript 引擎中。 Source
资源
Read more about these changes on the v8.dev blog: https://v8.dev/blog/fast-async#improved-developer-experience在 v8.dev 博客上阅读有关这些更改的更多信息: https ://v8.dev/blog/fast-async#improved-developer-experience
Because you can just因为你可以
async function() {
return foo();
}
The returned result of async function
always is Promise
, no matter you return the exact value or another Promise
object inside the function body async function
的返回结果总是Promise
,无论你返回的是确切的值还是函数体内的另一个Promise
对象
It seems many are debating the usefulness of return await
in the comments.似乎很多人在评论中争论
return await
的有用性。 Let me add a demonstration that shows how the stacktrace is affected.让我添加一个演示,说明堆栈跟踪是如何受到影响的。
In my opinion, skipping await
is a misguided attempt at some sense of "optimization", saving 6 characters and a microtask (EDIT: ShortFuse just showed that it is actually not saving but adding a microtask in current v8 ) at the cost of stacktraces, try-catches, refactorability and code consistency.在我看来,跳过
await
是在某种“优化”意义上的错误尝试,以堆栈跟踪为代价保存 6 个字符和一个微任务(编辑: ShortFuse 刚刚表明它实际上不是在保存,而是在当前 v8 中添加了一个微任务),尝试捕获、可重构性和代码一致性。 The rule of the thumb is simple: have an async call, await it (unless you are doing fancy stuff like parallelism or async caching).经验法则很简单:有一个异步调用,等待它(除非你正在做一些花哨的东西,比如并行或异步缓存)。 I believe we should stick to the rule of thumb and always use
return await
, and switch off that no-return-await
eslint rule.我相信我们应该坚持经验法则并始终使用
return await
,并关闭那个no-return-await
eslint 规则。
little demo:小演示:
async function main() { console.log("\nStatcktrace with await shows testStackWithAwait:"); await testStackWithAwait().catch(logStack); console.log("\nStatcktrace without await hides testStackWithoutAwait:"); await testStackWithoutAwait().catch(logStack); console.log("\nFinally happens before try block ends without await:"); 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('inside'); } async function testFinallyWithoutAwait() { try { return fnThatLogs(); // bad } finally { console.log('finally'); } } function logStack(e) { console.log(e.stack); } function delay(timeout, value) { return new Promise(resolve => { setTimeout(() => { resolve(value); }, timeout); }); } main().catch(console.error);
On Chrome 103 on Windows I get the following logs:在 Windows 上的 Chrome 103 上,我得到以下日志:
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 hides testStackWithoutAwait:
Error
at fnThatThrows (https://stacksnippets.net/js:23:9)
at async main (https://stacksnippets.net/js:16:3)
Finally happens before try block ends without await:
finally
inside
The significant difference between return asyncFunc and return await Promise.resolve() is by following the second approach you can catch an error if something wrong inside async function. return asyncFunc 和 return await Promise.resolve() 之间的显着区别在于,通过遵循第二种方法,如果 async 函数内部出现问题,您可以捕获错误。
function afunction() {
return asyncFun();
}
// with await
function afunction() {
try {
return await asyncFun();
} catch(err) {
handleError(err);
// return error result;
}
}
Oh I think is easy to understand, we put "await" when we wait for a specific value in order to continue a process, if the process is finished (look at the return), we don't need the await syntax anymore so.哦,我想很容易理解,当我们等待一个特定的值以继续一个过程时,我们放了“await”,如果这个过程完成了(看看返回),我们就不需要 await 语法了。
return await foo(); //is redundant
return foo(); //is the correct way
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.