协慌网

登录 贡献 社区

什么是 sleep()的 JavaScript 版本?

有没有比使用下面的pausecomp函数( 从这里获取 )更好的方法来在 JavaScript 中设计sleep

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

这不是JavaScriptSleep的重复- 动作之间的延迟 ; 我希望在函数中间实现真正的睡眠 ,而不是在执行代码之前的延迟。

答案

2017 年更新

自从 2009 年提出这个问题以来,JavaScript 已经发生了重大变化。所有其他答案现在已经过时或过于复杂。这是目前的最佳做法:

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

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two seconds later');
}

demo();

就是这个。 await sleep(<duration>)

您可以在 Runkit 上试用此代码。注意,

  1. await只能在前缀为async关键字的函数中执行。 Runkit 在执行之前将代码包装在异步函数中。
  2. await只暂停当前的async功能

两个新的 JavaScript 功能帮助编写了这个实际的 “睡眠” 功能:

兼容性

如果由于某种原因,你正在使用的节点比 7 年长,或瞄准旧的浏览器, async / await仍然可以通过使用巴别塔 (一种工具,将transpile的 JavaScript + 新功能集成到普通的旧的 JavaScript),与transform-async-to-generator插件 。跑

npm install babel-cli --save

创建.babelrc

{
  "plugins": [
    "transform-async-to-generator",
  ]
}

然后运行你的代码

node_modules/babel-cli/bin/babel-node.js sleep.js

但是,如果您使用的是 Node 7 或更高版本,或者您的目标是现代浏览器,那么您也不需要这样做。

(参见2016 年更新的答案

我认为想要执行某个操作,等待,然后执行其他操作是完全合理的。如果您习惯于使用多线程语言编写,那么在线程唤醒之前,您可能会想要在一段时间内执行执行。

这里的问题是 JavaScript 是一个基于事件的单线程模型。虽然在特定情况下,让整个引擎等待几秒钟可能会很好,但总的来说这是不好的做法。假设我想在编写自己的函数时使用你的函数?当我打电话给你的方法时,我的方法都会冻结。如果 JavaScript 可以某种方式保存你的函数的执行上下文,将它存储在某个地方,然后将其恢复并稍后继续,然后就可以发生睡眠,但这基本上就是线程化。

所以你几乎坚持别人的建议 - 你需要将你的代码分解成多个功能。

那么你的问题是一个错误的选择。没有办法以你想要的方式睡觉,你也不应该寻求你建议的解决方案。

在 JavaScript 中,我重写了每个函数,以便它可以尽快结束。您希望浏览器重新进入控制状态,以便进行 DOM 更改。

每次我想在函数中间进行睡眠时,我都会重构使用setTimeout()

我要编辑这个答案因为我觉得这很有用:

在任何语言中臭名昭着的睡眠或延迟功能都备受争议。有些人会说应该总是有一个信号或回调来激发给定的功能,其他人会争辩说,有时候任意延迟的时刻都是有用的。我说每个人都有自己和一个规则在这个行业中永远不会有任何规定。

编写一个 sleep 函数很简单,使用 JavaScript Promises 更加实用:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});