474

下面的这个功能不像我想要的那样工作;作为一个JS新手,我不知道为什么。

我需要它等待 5 秒钟,然后再检查是否newState-1.

目前,它不等待,它只是立即检查。

function stateChange(newState) {
  setTimeout('', 5000);

  if(newState == -1) {
    alert('VIDEO HAS STOPPED');
  }
}
4

16 回答 16

451

您必须将代码放入您提供的回调函数中setTimeout

function stateChange(newState) {
    setTimeout(function () {
        if (newState == -1) {
            alert('VIDEO HAS STOPPED');
        }
    }, 5000);
}

任何其他代码将立即执行。

于 2013-01-09T01:11:34.453 回答
377

这是使用新的 async/await语法的解决方案。

请务必检查浏览器支持,因为这是 ECMAScript 6 引入的语言功能。

实用功能:

const delay = ms => new Promise(res => setTimeout(res, ms));

用法:

const yourFunction = async () => {
  await delay(5000);
  console.log("Waited 5s");

  await delay(5000);
  console.log("Waited an additional 5s");
};

这种方法的优点是它使您的代码看起来和行为像同步代码。

于 2017-11-24T21:52:32.533 回答
233

您真的不应该这样做,正确使用 timeout 是解决 OP 问题以及您只想在一段时间后运行某些东西的任何其他场合的正确工具。Joseph Silber 在他的回答中很好地证明了这一点。但是,如果在某些非生产情况下,您确实想将主线程挂起一段时间,则可以这样做。

function wait(ms){
   var start = new Date().getTime();
   var end = start;
   while(end < start + ms) {
     end = new Date().getTime();
  }
}

以以下形式执行:

console.log('before');
wait(7000);  //7 seconds in milliseconds
console.log('after');

我来到这里是因为我正在构建一个简单的测试用例,用于围绕长时间运行的阻塞操作(即昂贵的 DOM 操作)对混合异步操作进行排序,这是我模拟的阻塞操作。它很适合这份工作,所以我想我把它发布给其他有类似用例的人。即便如此,它还是在 while 循环中创建了一个 Date() 对象,如果它运行的时间足够长,它可能会使 GC 不堪重负。但我怎么强调都不为过,这仅适用于测试,对于构建任何实际功能,您应该参考 Joseph Silber 的回答。

于 2015-10-29T12:22:30.283 回答
107

如果你在一个异步函数中,你可以简单地在一行中完成:

console.log(1);
await new Promise(resolve => setTimeout(resolve, 3000)); // 3 sec
console.log(2);

仅供参考,如果目标是 NodeJS,您可以根据需要使用它(这是一个预定义的承诺 setTimeout 函数):

await setTimeout[Object.getOwnPropertySymbols(setTimeout)[0]](3000) // 3 sec
于 2018-07-23T16:02:35.857 回答
50

使用这样的延迟函数:

var delay = ( function() {
    var timer = 0;
    return function(callback, ms) {
        clearTimeout (timer);
        timer = setTimeout(callback, ms);
    };
})();

用法:

delay(function(){
    // do stuff
}, 5000 ); // end delay

致谢:如何延迟 .keyup() 处理程序,直到用户停止输入?

于 2015-01-27T15:06:28.807 回答
46

您不应该只是尝试在 javascript 中暂停 5 秒。它不是那样工作的。您可以安排一个代码函数在 5 秒后运行,但是您必须将稍后要运行的代码放入一个函数中,该函数之后的其余代码将继续立即运行。

例如:

function stateChange(newState) {
    setTimeout(function(){
        if(newState == -1){alert('VIDEO HAS STOPPED');}
    }, 5000);
}

但是,如果你有这样的代码:

stateChange(-1);
console.log("Hello");

console.log()语句将立即运行。它不会等到stateChange()函数中的超时触发之后。您不能只暂停 JavaScript 执行一段预定的时间。

相反,您想要运行延迟的任何代码都必须在setTimeout()回调函数内(或从该函数调用)。

如果您确实尝试通过循环“暂停”,那么您实际上会“挂起”Javascript 解释器一段时间。因为 Javascript 仅在单个线程中运行您的代码,所以当您循环时,没有其他任何东西可以运行(没有其他事件处理程序可以被调用)。因此,循环等待某个变量更改将永远不会起作用,因为没有其他代码可以运行来更改该变量。

于 2013-01-09T01:13:47.263 回答
12

该解决方案来自React Native 的刷新控制文档

function wait(timeout) {
    return new Promise(resolve => {
        setTimeout(resolve, timeout);
    });
}

要将其应用于 OP 的问题,您可以将此功能与以下内容配合使用await

await wait(5000);
if (newState == -1) {
    alert('Done');
}
于 2020-02-19T21:57:29.477 回答
11

尝试这个:

//the code will execute in 1 3 5 7 9 seconds later
function exec() {
    for(var i=0;i<5;i++) {
        setTimeout(function() {
            console.log(new Date());   //It's you code
        },(i+i+1)*1000);
    }
}
于 2015-11-03T11:51:21.627 回答
8

创建这样一个等待毫秒的函数的最佳方法,此函数将等待参数中提供的毫秒数:

function waitSeconds(iMilliSeconds) {
    var counter= 0
        , start = new Date().getTime()
        , end = 0;
    while (counter < iMilliSeconds) {
        end = new Date().getTime();
        counter = end - start;
    }
}

于 2015-05-02T12:20:04.280 回答
8
setTimeout(function() {
     $('.message').hide();
}, 5000);

这将在 5 秒后隐藏 '.message' div。

于 2020-09-30T18:47:00.963 回答
6

根据 Joseph Silber 的回答,我会这样做,更通用一点。

您将拥有您的功能(让我们根据问题创建一个):

function videoStopped(newState){
   if (newState == -1) {
       alert('VIDEO HAS STOPPED');
   }
}

你可以有一个等待功能:

function wait(milliseconds, foo, arg){
    setTimeout(function () {
        foo(arg); // will be executed after the specified time
    }, milliseconds);
}

最后,您将拥有:

wait(5000, videoStopped, newState);

这是一个解决方案,我宁愿不在等待函数中使用参数(只使用foo();而不是foo(arg);),但这只是示例。

于 2017-07-13T14:25:24.600 回答
6

您可以通过对函数( async 和 await )进行小的更改来增加延迟。

const addNSecondsDelay = (n) => {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, n * 1000);
  });
}

const asyncFunctionCall = async () {

  console.log("stpe-1"); 
  await addNSecondsDelay(5);
  console.log("step-2 after 5 seconds delay"); 

}

asyncFunctionCall();
于 2020-01-09T10:30:23.997 回答
-1

尝试这个。当我不得不限制 API 调用时使用了类似的方法。

const sleep = (delay) => new Promise ((resolve) => setTimeout (resolve, delay))

甚至适用于 for..of 循环:

for (const item of items) {
  console.dir('Waiting 2 seconds before doing anything...')
  await sleep(2000)
  // Code below here will be executed after 2 seconds
  // Rinse and repeat
}
于 2022-02-24T14:21:39.267 回答
-1

使用 angularjs:

$timeout(function(){
if(yourvariable===-1){
doSomeThingAfter5Seconds();
}
},5000)
于 2017-09-14T05:40:38.330 回答
-4

创建新的 Js 函数

function sleep(delay) {
        var start = new Date().getTime();
        while (new Date().getTime() < start + delay);
      }

当您想延迟执行时调用该函数。在 int 中使用毫秒作为延迟值。

####Some code
 sleep(1000);
####Next line
于 2018-05-22T08:15:26.000 回答
-5

我用它从 Edge 或 IE 运行 PC 游戏。两个自我在 7 秒后关闭。

Firefox 和 Google Chrome 不能用于以这种方式启动游戏。

    <html>
    <body>
    <a href="E:\game\game.exe" name="game" onmouseout="waitclose(7000);"> game
    <img src="game.jpg" width="100%" height="97%" ></a>
    <script>
    function waitclose(ms){
     var start = new Date().getTime();var end=start;
     while(end < start + ms) {end = new Date().getTime();}
    window.open('', '_self', ''); window.close();
    }
    </script>
    </body>
    </html>
于 2018-08-05T20:53:36.820 回答