ECMAScript7 async / await不一致的行为取决于是否在箭头函数中使用括号

时间:2017-08-04 22:29:22

标签: 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));
}

(async () => {
  console.log('a');
  await sleep(5000);
  console.log('b');
})()

正如所料,这会将 a 写入控制台,等待 5秒,然后将 b 写入控制台。

使用箭头函数缩短表示法以返回 Promise

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

(async () => {
  console.log('a');
  await sleep(5000);
  console.log('b');
})()

正如所料,此代码的行为相同。 a b 会写入控制台,其间的间隔为 5000毫秒

以下代码不起作用。唯一的区别是我没有在第一行的括号中包含 Promise 的返回。

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

(async () => {
  console.log('a');
  await sleep(5000);
  console.log('b');
})()

在这种情况下,等待睡眠不起作用。事实上,这段代码完全没有任何作用。它不会将任何内容记录到控制台,而不是 a 而不是 b

我认为自己很有经验,但我现在还不明白这一点。为什么括号在这种特殊情况下很重要?返回值是相同的,对吗?怎么没有控制台记录 a 字符?

有人请向我详细解释为什么会这样。这是一个错误还是我自己需要睡觉?

非常感谢。

1 个答案:

答案 0 :(得分:6)

这是箭头功能之后的分号。写

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

它会起作用。请注意,下一行以(开头,这是一个语法上有效的延续,因此ASI不会跳入。您的代码被解析并解释为

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

但永远不会调用函数sleep