我现在一直在JavaScript中反复遇到一个奇怪的问题.我似乎无法延迟setInterval.
会发生什么的一个小例子:
var loop;
var count;
loop = setInterval(start, 30);
function start() {
//Some code
delay();
//Some more code
}
function delay() {
setTimeout(function () {
count++;
//Animation code
if (count <= 1000) delay();
}, 100);
}
现在我想要做的是,执行’some code’部分,在’动画代码’执行时什么也不做,然后执行’更多代码’部分.
发生的事情是“更多代码”部分和延迟功能同时执行.我在调用延迟函数之前尝试了clearInterval(循环),并在延迟函数完成它的执行后重新启动它,但是“更多的代码”似乎仍然执行了一次.
我怎样才能解决这个问题?请举例说明详细说明.
解决方法:
你的delay()函数实际上并没有阻止你的start()函数完成.
在Javascript中,setTimeout()不会暂停执行Javascript.相反,它所做的是安排传递给setTimeout()的回调在将来的某个时间运行,其余代码继续运行.
如果你想在一段时间内延迟某段代码块的执行,那么你必须将这段代码放在setTimeout()回调中,如下所示:
setTimeout(function() {
// the code in here will run some time in the future
}, delayTime);
// the code here will run immediately
Javascript中经常描述的方式是对setTimeout()的调用是非阻塞的.它不会停止或暂停当前执行线程的运行.实际上,执行线程将运行完成.相反,setTimeout()会调度将在特定时间调用的回调函数(当没有其他Javascript代码正在运行时).
因为Javascript是单线程的,所以即使使用非常长的while()循环,它也几乎无法循环以尝试创建延迟.问题是,当你循环时,没有其他Javascript代码可以运行,所以没有其他状态可以改变,所以你等待改变的循环条件在循环时不会改变.这通常只会导致死锁类型的条件,并最终浏览器意识到Javascript线程被“卡住”并将提示中止它.
相反,您使用事件和将来的回调进行编程.您设置了一个事件或计时器回调,以便在将来发生某些事情时调用它,然后将相关代码放入该回调或事件处理程序中.还有更多高级工具可以帮助管理这些工具,例如promises或异步库,但它们只是建立在相同的回调机制之上.