为什么没有回报 - wait vs const x =等待



之间有什么区别
return await foo()

const t = await foo();
return t

http://eslint.org/docs/rules/no-return-await

基本上,因为 return await是多余的。

从您实际使用async函数的方式略高的级别上查看它:

const myFunc = async () => {
  return await doSomething();
};
await myFunc();

任何async函数都将返回Promise,并且必须作为Promise(直接作为Promise,或者通过await -ing(处理。

如果您的await在函数内部,则是多余的,因为外部功能也将以某种方式进行await,因此没有理由不仅会将Promise发送并让外部事物处理它。

这不是句法错误或不正确,通常不会引起问题。这完全是多余的,这就是为什么衬里触发它的原因。

使用return await确实在Node.js,Chrome和其他一些浏览器的V8引擎中具有一些新引入的好处:

v8引入了一个--async-stack-traces标志,默认情况下启用了V8 V7.3(node.js v12.0.0(。

此标志通过使用异步函数调用stack跟踪丰富错误堆栈属性来提供改进的开发人员体验。

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)

请注意,通过调用return bar(); foo()函数调用根本在错误堆栈中出现。将其更改为return await bar();给出了更好的错误堆栈输出:

async function foo() {
  return await bar();
}
foo();
Error: BEEP BEEP
    at bar (<anonymous>:7:9)
    at async foo (<anonymous>:2:10)

这确实提供了更好的错误堆栈跟踪,因此始终在等待您的承诺。

此外,异步/等待现在优于书面承诺:

async/await立即胜过手写的承诺代码。这里的关键要点是,我们通过修补规格大大降低了异步函数的开销 - 不仅在V8,而且在所有JavaScript引擎中。来源

在v8.dev博客上阅读有关这些更改的更多信息:https://v8.dev/blog/fast-async#impreved-developer-experience

,因为您只能

async function() {
  return foo();
}

async function的返回结果始终是Promise,无论您返回函数主体内的确切值或其他Promise对象

更新: no-return-await规则现在为已弃用。世界正在治愈。

似乎许多人在评论中辩论return await的有用性。让我添加一个演示,展示了堆栈的影响。

我认为,跳过await是某种误导的尝试"优化","优化",保存6个字符和一个微型掩体(编辑:ShortFuse只是表明它实际上是在保存,但在当前V8中添加了MicroTask(堆栈跟踪,试用,可重构性和代码一致性的成本。拇指的规则很简单:如果您有异步呼叫,请等待它(除非您正在做诸如平行性或异步缓存之类的精美工作(。我相信我们应该坚持经验法则,始终使用使用return await,然后关闭no-return-await ESLINT规则。

小演示:

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);

在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

返回asyncfunc和return等待Promise.resolve((之间的显着差异是通过遵循第二种方法,您可以在异步函数中发生错误的情况下捕获错误。

function afunction() {
  return asyncFun();
}
   
// with await
async function afunction() {
  try {
    return await asyncFun();
  } catch(err) {
    handleError(err);
    // return error result;
  }
}
   
    

哦,我认为很容易理解,我们等待着"等待"当我们等待特定值以继续过程时,如果该过程完成(查看返回(,我们不再需要等待语法。

return await foo(); //is redundant
return foo(); //is the correct way

最新更新