实际上,您可以使用与pausecomp函数相同的while循环实现sleep()(这基本上是相同的):
const sleep = (seconds) => {
const waitUntil = new Date().getTime() + seconds * 1000
while(new Date().getTime() < waitUntil) {
// do nothing
}
}
您可以像这样使用sleep()方法:
const main = () => {
const a = 1 + 3
// Sleep 3 seconds before the next action
sleep(3)
const b = a + 4
// Sleep 4 seconds before the next action
sleep(4)
const c = b + 5
}
main()
这就是我想象你会使用睡眠功能的方式,而且读起来相对简单。我借鉴了另一篇文章《JavaScript中的睡眠——动作之间的延迟》,以展示您可能打算如何使用它。
不幸的是,你的电脑会变热,所有工作都会受阻。如果在浏览器中运行,该选项卡将停止,用户将无法与页面交互。
如果您将代码重组为异步的,那么您可以将setTimeout()作为与其他文章相同的睡眠函数。
// define sleep using setTimeout
const sleep = (seconds, callback) => setTimeout(() => callback(), seconds * 1000)
const main = () => {
const a = 1 + 3
let b = undefined
let c = undefined
// Sleep 3 seconds before the next action
sleep(3, () => {
b = a + 4
// Sleep 4 seconds before the next action
sleep(4, () => {
c = b + 5
})
})
}
main()
正如你所说,这不是你想要的。我修改了Sleep in JavaScript中的示例-动作之间的延迟,以说明为什么会出现这种情况。当您添加更多动作时,要么需要将逻辑拉入单独的函数,要么将代码嵌套得越来越深(回调地狱)。
为了解决“回调地狱”,我们可以使用promise来定义睡眠:
const sleep = (seconds) => new Promise((resolve => setTimeout(() => resolve(), seconds * 1000)))
const main = () => {
const a = 1 + 3
let b = undefined
let c = undefined
// Sleep 3 seconds before the next action
return sleep(3)
.then(() => {
b = a + 4
// Sleep 4 seconds before the next action
return sleep(4)
})
.then(() => {
c = b + 5
})
}
main()
Promise可以避免深度嵌套,但看起来仍然不像我们最初使用的常规同步代码。我们希望编写看起来同步的代码,但没有任何缺点。
让我们再次使用async/await重写我们的主方法:
const sleep = (seconds) => new Promise((resolve => setTimeout(() => resolve(), seconds * 1000)))
const main = async () => {
const a = 1 + 3
// Sleep 3 seconds before the next action
await sleep(3)
const b = a + 4
// Sleep 4 seconds before the next action
await sleep(4)
const c = b + 5
}
main()
使用async/await,我们可以调用sleep(),就好像它是一个同步的阻塞函数一样。这解决了您可能在其他帖子中使用回调解决方案时遇到的问题,并避免了长时间循环的问题。