我在使用现代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 字符?
有人请向我详细解释为什么会这样。这是一个错误还是我自己需要睡觉?
非常感谢。
答案 0 :(得分:6)
这是箭头功能之后的分号。写
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
// ^
它会起作用。请注意,下一行以(
开头,这是一个语法上有效的延续,因此ASI不会跳入。您的代码被解析并解释为
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))(async () => { … })()
但永远不会调用函数sleep
。