下面这个函数并没有像我想要的那样工作;作为一个JS新手,我不明白为什么。
我需要它等待5秒,然后检查newState是否为-1。
newState
-1
目前,它不会等待,它只是直接检查。
function stateChange(newState) { setTimeout('', 5000); if(newState == -1) { alert('VIDEO HAS STOPPED'); } }
你必须把你的代码放在你提供给setTimeout的回调函数中:
setTimeout
function stateChange(newState) { setTimeout(function () { if (newState == -1) { alert('VIDEO HAS STOPPED'); } }, 5000); }
任何其他代码将立即执行。
你不应该只是尝试在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执行。
console.log()
stateChange()
相反,任何想要运行延迟的代码都必须在setTimeout()回调函数中(或从该函数调用)。
setTimeout()
如果您试图通过循环来“暂停”,那么您实际上是在“挂起”Javascript解释器一段时间。因为Javascript只在一个线程中运行代码,当循环时,其他任何东西都不能运行(不能调用其他事件处理程序)。因此,循环等待某个变量的改变永远不会起作用,因为没有其他代码可以运行来改变该变量。
像这样使用延迟函数:
var delay = ( function() { var timer = 0; return function(callback, ms) { clearTimeout (timer); timer = setTimeout(callback, ms); }; })();
用法:
delay(function(){ // do stuff }, 5000 ); // end delay
学分:# EYZ0
创建这样一个以毫秒为单位等待的函数的最好方法是,这个函数将在参数中提供的毫秒内等待:
function waitSeconds(iMilliSeconds) { var counter= 0 , start = new Date().getTime() , end = 0; while (counter < iMilliSeconds) { end = new Date().getTime(); counter = end - start; } }
你真的不应该这么做,正确使用超时是解决OP问题的正确工具,在任何其他情况下,你只是想在一段时间后运行一些东西。约瑟夫·西尔伯在他的回答中很好地证明了这一点。但是,如果在一些非生产的情况下,您真的<强> < / >强想要挂起主线程一段时间,这将做到这一点。
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运行的时间足够长,它可能会淹没GC。但是我怎么强调都不为过,这只适用于测试,对于构建任何实际功能,您应该参考Joseph Silber的回答。
试试这个:
//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); } }
基于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);),但这是为示例。
foo();
foo(arg);
下面是一个使用新 异步/等待语法的解决方案。
一定要选中浏览器支持,因为这是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"); };
这种方法的优点是,它使您的代码看起来和行为起来像同步代码。
Node.js 16提供了一个内置的基于承诺的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"); };
⚠️为了记录,您可能会尝试使用等待函数来规避竞争条件(例如,在测试异步代码时)。这很少是个好主意。
创建新的Js函数
function sleep(delay) { var start = new Date().getTime(); while (new Date().getTime() < start + delay); }
当您希望延迟执行时,请调用该函数。在int中使用毫秒作为延迟值。
####Some code sleep(1000); ####Next line
如果你在异步函数中,你可以简单地在一行中完成:
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
您可以通过对函数(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();
这个解决方案来自用于刷新控件的React Native文档:
function wait(timeout) { return new Promise(resolve => { setTimeout(resolve, timeout); }); }
要将此应用于OP的问题,你可以使用这个函数与await协调使用:
await
await wait(5000); if (newState == -1) { alert('Done'); }
setTimeout(function() { $('.message').hide(); }, 5000);
这将隐藏'。5秒后消息' div。
如果你有一个asyn函数,你可以这样做:
await new Promise(resolve => setTimeout(resolve, 5000));