Javascript ECMAScript 7异步/等待不一致行为取决于是否在arrow函数中使用括号

Javascript ECMAScript 7异步/等待不一致行为取决于是否在arrow函数中使用括号,javascript,async-await,Javascript,Async Await,在使用现代ES6+async/await时,我在Google Chrome 60.0.3112.78(官方版本)(64位)中遇到了不一致的行为,这取决于我是否在返回承诺的箭头函数中使用括号。Node.js中也会发生同样的情况。我很难理解为什么 我知道这不是如何实现sleep()函数,但它是最简单的演示方法。考虑下面的示例代码片段。 function sleep(ms = 0) { return new Promise(resolve => setTimeout(resolve, ms)

在使用现代ES6+async/await时,我在Google Chrome 60.0.3112.78(官方版本)(64位)中遇到了不一致的行为,这取决于我是否在返回承诺的箭头函数中使用括号。Node.js中也会发生同样的情况。我很难理解为什么

我知道这不是如何实现sleep()函数,但它是最简单的演示方法。考虑下面的示例代码片段。

function sleep(ms = 0) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

(async () => {
  console.log('a');
  await sleep(5000);
  console.log('b');
})()
如预期,这将向控制台写入a,等待5秒,然后向控制台写入b


使用箭头函数返回承诺的简短表示法

正如所料,此代码的行为相同ab5000毫秒的间隔写入控制台


以下代码不起作用。唯一的区别是,我没有在第一行的括号中包装承诺的返还

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))

(async () => {
  console.log('a');
  await sleep(5000);
  console.log('b');
})()
在这种情况下,等待睡眠不起作用。事实上,这段代码完全不起任何作用。它不会将任何内容记录到控制台,而不是ab

我认为自己很有经验,但目前我还不明白。为什么括号在这种特殊情况下很重要?返回值是相同的,对吗?为什么连字符a都没有被记录

有人请给我解释一下为什么会这样。这是虫子还是我自己需要睡觉


非常感谢。

重要的是箭头函数后面的分号。写

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
//                                                                 ^
它会起作用的。请注意,下一行以
)开头,这是语法上有效的延续,因此不会跳入。您的代码被解析并解释为

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))(async () => { … })()

但是函数
sleep
永远不会被调用。

@它们是,但是如果您想省略分号并让它们在可能的情况下自动插入,您将忽略以
[
/
+
-
`
。哈哈,是的,但是这个bug的模糊性让我很感激额外的击键。谢谢!你是对的,我不敢相信我错过了。呸!顺便说一句,我实际上从不使用分号,除非没有其他方法,并且相信你可以通过这个习惯。但我有偏见。再次感谢!:)“理由是总是包含分号比试图记住分号是必需的还是不必需的更容易,从而减少引入错误的可能性。”@JochemStoel我假设您至少浪费了一个小时来找出代码没有按预期工作的原因。自动分号插入(ASI)被认为是JavaScript中比较有争议的功能之一。我们应该将ASI视为不存在。相关:@4castle如果您提到,我建议使用函数声明(
function sleep(ms){return…}
),它根本不需要分号:-)
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))(async () => { … })()