在 Javascript 中设置延迟

IT技术 javascript
2021-01-29 09:49:37

我需要在我的 Javascript 代码中添加大约 100 毫秒的延迟,但我不想使用对象setTimeout功能,window也不想使用忙循环。有没有人有什么建议?

6个回答

不幸的是,这setTimeout()是在不阻塞 UI 的情况下暂停脚本执行的唯一可靠方法(不是唯一方法,而是唯一可靠方法)。

其实用起来并不难,不如写成这样:

var x = 1;

// Place mysterious code that blocks the thread for 100 ms.

x = x * 3 + 2;
var y = x / 2;

你用setTimeout()这种方式重写它:

var x = 1;
var y = null; // To keep under proper scope

setTimeout(function() {
    x = x * 3 + 2;
    y = x / 2;
}, 100);

我知道使用setTimeout()比理想的sleep()功能需要更多的思考,但不幸的是后者不存在。有许多变通方法可以尝试实现此类功能。一些使用忙循环:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

其他人使用XMLHttpRequest与服务器脚本捆绑在一起,该脚本在返回结果之前会休眠一段时间

不幸的是,这些都是变通办法,可能会导致其他问题(例如冻结浏览器)。建议简单地坚持推荐的方式,即setTimeout())。

我不相信 setTimeout() 有任何耻辱感,只是它并不总是很容易产生预期的效果。举例来说,如果您想在进程密集型循环中将处理器闲置一小段时间以避免锁定浏览器。对于没有经验的 JavaScript 程序员来说,使用 setTimeout 实现这个结果可能很困难。
2021-03-15 09:49:37
@James M.:完全同意……我一直不明白为什么会有这么大的污名setTimeout()
2021-03-27 09:49:37
我是 js 新手。我将如何调用上述延迟脚本?我有一个循环试图延迟使用此功能。我试过函数睡眠(2000){...}。但这行不通。
2021-04-01 09:49:37
该脚本对我的工作时间长达 9 秒左右。之后它会停留大约 9 秒。也许就是这个1e7value?
2021-04-05 09:49:37
“但遗憾的是后者并不存在。” 您的意思是说“后者”吗?
2021-04-07 09:49:37

如果你对 ES2017 没问题,那await很好:

const DEF_DELAY = 1000;

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

await sleep(100);

请注意,该await部分需要在异步函数中:

//IIAFE (immediately invoked async function expression)
(async()=>{
  //Do some stuff
  await sleep(100);
  //Do some more stuff
})()

我只是遇到了一个问题,需要正确解决这个问题。

通过 Ajax,脚本获取 X (0-10) 条消息。我想做的是:每 10 秒向 DOM 添加一条消息。

我最终得到的代码:

$.each(messages, function(idx, el){
  window.setTimeout(function(){
    doSomething(el);
  },Math.floor(idx+1)*10000);
});

基本上,将超时视为脚本的“时间线”。

这是我们想要编码的内容:

DoSomething();
WaitAndDoNothing(5000);
DoSomethingOther();
WaitAndDoNothing(5000);
DoEvenMore();

这就是我们需要告诉 JAVASCRIPT 的方式:

At Runtime 0    : DoSomething();
At Runtime 5000 : DoSomethingOther();
At Runtime 10000: DoEvenMore();

希望这可以帮助。

感谢您解释 SetTimeOut 行为的答案。问题是,当代码很长或取决于服务器响应时,甚至很难在几秒钟内将实际时间线可视化。
2021-03-20 09:49:37

这个线程有一个很好的讨论和一个有用的解决方案:

function pause( iMilliseconds )
{
    var sDialogScript = 'window.setTimeout( function () { window.close(); }, ' + iMilliseconds + ');';
    window.showModalDialog('javascript:document.writeln ("<script>' + sDialogScript + '<' + '/script>")');
}

不幸的是,这似乎在某些版本的 IE 中不起作用,但是如果证明这对您来说是个问题,该线程还有许多其他有value的建议。

似乎是一个等待问题的解决方案。我想不出任何一种情况setTimeout无法完成它的工作。但是创造力+1。:)
2021-04-11 09:49:37

实际上只setTimeout适用于该工作,通常您不能将不确定的方法设置为繁忙循环的确切延迟。

您不能使用 setTimeout 暂停 js 解释器。
2021-04-11 09:49:37
您只能在延迟后调用函数。setTimeout 不是“阻塞”。其余代码按预期工作。
2021-04-11 09:49:37