有没有比下面的pausecomp函数(取自此处)更好的方法来设计JavaScript中的睡眠?

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

这不是JavaScript中的Sleep的重复-动作之间的延迟;我希望在函数的中间有一个真正的睡眠,而不是在代码执行之前有一段延迟。


当前回答

你不能在JavaScript中做这样的睡眠,或者更确切地说,你不应该这样做。运行sleep或while循环将导致用户的浏览器挂起,直到循环完成。

使用您引用的链接中指定的计时器。

其他回答

让事情看起来像大多数人想要的更好的解决方案是使用匿名函数:

alert('start');
var a = 'foo';
// Lots of code
setTimeout(function(){  // Beginning of code that should run AFTER the timeout
    alert(a);
    // Lots more code
}, 5000);  // Put the timeout here

这可能是最接近你想要的东西。

注意,如果你需要多次睡眠,这可能会在匆忙中变得很难看,你可能需要重新考虑你的设计。

使用TypeScript:

这里有一个可以等待的快速sleep()实现。这与上面的答案尽可能相似。它在功能上是等效的,除了ms被键入为TypeScript的数字。

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

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

demo();

就这样。等待睡眠(<持续时间>)。

注意,

await只能在前缀为async关键字的函数中执行,或者在某些环境中在脚本的顶层执行(例如,Chrome DevTools控制台或Runkit)。await只暂停当前的异步函数。

使用更好的DX实现更安全的异步睡眠

我使用睡眠进行调试。。。我忘了用wait太多次了。让我挠头。我在写下面的实时片段时忘记使用await。。。不再!

如果您在1毫秒内运行了两次,下面的睡眠功能会提醒您。如果您确定使用了await,它还支持传递一个相当的参数。它不会投掷,因此可以安全地用作睡眠的替代品。享受

是的,实时片段中有一个JavaScript版本。

// Sleep, with protection against accidentally forgetting to use await
export const sleep = (s: number, quiet?: boolean) => {
  const sleepId = 'SLEEP_' + Date.now()
  const G = globalThis as any
  if (G[sleepId] === true && !quiet) {
    console.error('Did you call sleep without await? use quiet to hide msg.')
  } else {
    G[sleepId] = true
  }
  return new Promise((resolve) => {
    !quiet && setTimeout(() => {
      delete G[sleepId]
    }, 1)
    setTimeout(resolve, (s * 1000) | 0)
  })
}

//睡眠,防止意外忘记使用等待常量睡眠=(s,安静)=>{constsleepId='SLEEP_'+Date.now()const G=全局此if(G[sleepId]==true&&!quiet){console.error('您是否在没有等待的情况下调用sleep?使用quiet隐藏消息。')}其他{G[sleepId]=真}return new Promise((resolve)=>{!quiet&&setTimeout(()=>{删除G[sleepId]}, 1)setTimeout(解析,(s*1000)|0)})}常量main=async()=>{console.log('休眠1秒…')等待睡眠(1)console.log('使用等待的目标…')睡眠(99)睡眠(99)等待睡眠(1,true)console.log(“开发人员快乐!”)}main()

与公认更容易阅读的相比:

const sleep = (s: number) =>
  new Promise((p) => setTimeout(p, (s * 1000) | 0))

简短的答案是否定的,而不是JavaScript本身。您的解决方案似乎是不让控制权回归环境的唯一途径。

如果环境不支持事件,这是必要的。他们可能也不支持setTimeout。

如果您处于事件驱动环境(如浏览器或Node.js)中,setTimeout绝对是最好的方法。

如果您使用的是Node.js,您可以看看fiber——一种对节点的原生C扩展,一种多线程模拟。

它允许您以阻塞光纤中的执行的方式进行真正的睡眠,但在主线程和其他光纤中是非阻塞的。

下面是他们自己自述文件中的一个例子:

// sleep.js

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

–结果如下:

$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)