问题描述
我按照W3Schools的本教程创建了一个图像幻灯片:https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_auto
它通过setTimeout()
使用递归函数自动滑动图像。这对用户的浏览器性能不利吗?还是可以不用担心使用它?
var slideIndex = 0;
showSlides();
function showSlides() {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("dot");
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
slideIndex++;
if (slideIndex > slides.length) {
slideIndex = 1
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active","");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className += " active";
setTimeout(showSlides,2000); // Change image every 2 seconds
}
解决方法
如果是递归的,则是指一个setTimeout
最终调用了另一个(或更常见的是本身),然后是不。
事实上,这是首选的解决方法。
通过使用setTimeout
,它可以使浏览器在两次更新之间进行一次中断以进行其他更新(也就是“非阻塞”)。
您也可以使用setInterval
并使其运行,但是问题是如果出现问题,则必须显式调用clearInterval
,否则它将继续抛出错误。 / p>
setTimeout
只会抛出一个错误并停止(因为它并没有引起进行另一个setTimeout
的调用)。 setTimeout
绝对是我以及其他许多人的首选方法。
它也不会产生任何类型的堆栈溢出(就像正常的递归函数递归时间过长一样,因为它在这种意义上并不是真正的递归。)
,由于浏览器无论如何应该在另外2秒内什么也不做,因此可以安全地忽略与setInterval()相比递归setTimeout()的任何假设开销。但是,当您使用setTimeout()精确模拟setInterval()时,您的程序可能会更难理解。因此,我宁愿使用setInterval进行幻灯片演示。
也就是说,在node.js上的某些应用程序中,我体验到setInterval()会有一点漂移,因此使用setTimeout()会导致更精确的计时。但是在幻灯片放映的用例中,可以忽略每个间隔几毫秒的微小漂移。
,调用setTimeout
时,JS运行时会安排执行指定的回调。这不是递归,因为我们不用等待来获取回调返回值。
尝试看setTimeout
就像是填满时间表的东西,基本上是塞特犬。如果您在8:00:00 AM调用setTimeout(callback,2000)
,则JS运行时可能会对您说:“好吧!我将在8:00:02 AM执行该回调,但是我仍然可以在等待时执行其他操作。 “
希望这很有帮助。