Answers:
您必须将代码放入提供给的回调函数中setTimeout
:
function stateChange(newState) {
setTimeout(function () {
if (newState == -1) {
alert('VIDEO HAS STOPPED');
}
}, 5000);
}
任何其他代码将立即执行。
您实际上不应该这样做,正确使用超时是解决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的答案。
这是使用新的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");
};
这种方法的优势在于,它使您的代码外观和行为类似于同步代码。
使用如下延迟函数:
var delay = ( function() {
var timer = 0;
return function(callback, ms) {
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
用法:
delay(function(){
// do stuff
}, 5000 ); // end delay
您不应该只是尝试在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仅在单个线程中运行代码,因此在循环时,其他任何东西都无法运行(无法调用其他事件处理程序)。因此,循环等待某些变量更改将永远无法进行,因为没有其他代码可以运行来更改该变量。
var t = new Date().getTime(); while (new Date().getTime() < t + millisecondsToLockupBrowser);
如果您使用的是异步功能,则只需一行即可:
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
创建这样的函数的最佳方法是等待毫秒,此函数将等待参数中提供的毫秒:
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);
那是一个解决方案,我宁愿不要在wait函数中使用参数(仅使用foo();
代替foo(arg);
),但这只是示例。
此解决方案来自React Native的文档,用于刷新控件:
function wait(timeout) {
return new Promise(resolve => {
setTimeout(resolve, timeout);
});
}
要将其应用于OP的问题,可以与以下功能配合使用此功能await
:
await wait(5000);
if (newState == -1) {
alert('Done');
}
您可以通过对函数进行少量更改(async和await)来增加延迟。
const add5SecondsDelay = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve('5 seconds');
}, 50000);
});
}
async function asyncFunctionCall() {
console.log("stpe-1");
const result = await add5SecondsDelay ();
console.log("step-2 after 5 seconds delay");
}
asyncFunctionCall();
创建新的Js函数
function sleep(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
要延迟执行时,请调用该函数。将int的毫秒数用作延迟值。
####Some code
sleep(1000);
####Next line
我用它从Edge或IE运行PC游戏。并在7秒钟后自动关闭IE Edge。
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>