繁体   English   中英

在执行下一行之前等待 5 秒

[英]Wait 5 seconds before executing next line

下面的这个 function 并没有像我想要的那样工作; 作为一个 JS 新手,我不明白为什么。

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

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

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

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

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

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

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

浏览器

这是使用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");
};

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

节点.js

Node.js 16 提供了基于 promise 的内置setTimeout版本,因此我们不必创建自己的实用程序函数:

import { setTimeout } from "timers/promises";

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

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

⚠️ 仅作记录,您可能很想使用等待函数来规避竞争条件(例如,在测试异步代码时)。 这很少是一个好主意。

您真的不应该这样做,正确使用 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 的回答。

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

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

使用这样的延迟函数:

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

用法:

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

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

您不应该只是尝试在 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 仅在单个线程中运行您的代码,所以当您循环时,没有其他任何东西可以运行(没有其他事件处理程序可以被调用)。 因此,循环等待某个变量更改将永远不会起作用,因为没有其他代码可以运行来更改该变量。

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

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

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

await wait(5000);
if (newState == -1) {
    alert('Done');
}
setTimeout(function() {
     $('.message').hide();
}, 5000);

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

尝试这个:

//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);
    }
}

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

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

根据 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); ),但这是示例。

您可以通过对函数( 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();

如果你有一个异步函数,你可以这样做:

await new Promise(resolve => setTimeout(resolve, 5000));

使用 angularjs:

$timeout(function(){
if(yourvariable===-1){
doSomeThingAfter5Seconds();
}
},5000)

我用它从 Edge 或 IE 运行 PC 游戏。 并且两个 self 在 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>

创建新的 Js 函数

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

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

####Some code
 sleep(1000);
####Next line

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM