这是一个非常简单的幻灯片的代码,它应该在 4 秒内显示 4 张图像,每秒一张图像。相反,我得到了 4 秒的延迟,然后所有图像都被绘制在彼此之上。我究竟做错了什么?
<html>
<head>
<script langugage="javascript">
// 4 images
var image0 = new Image();
image0.src = "img/image0.png";
var image1 = new Image();
image1.src = "img/image1.png";
var image0 = new Image();
image2.src = "img/image2.png";
var image3 = new Image();
image3.src = "img/image3.png";
// array of 4 images
images = new Array(image0, image1, image2, image3);
// this is the main function
function draw(){
myCanvas = document.getElementById('myCanvas');
ctx = myCanvas.getContext('2d');
counter=0; // this is the index of the next image to be shown
for (var i=0;i<images.length;i++){
setTimeout(draw_next_image, 1000);
ctx.clearRect(0, 0, myCanvas.width, myCanvas.height)
}
}
// this is the function called after each timeout to draw next image
function draw_next_image(){
ctx.drawImage(images[counter], 0, 0);
counter++;
if (counter>images.length) {counter=0;}
}
window.onload = draw;
</script>
</head>
<body>
<canvas id="myCanvas" width="800" height="600"></canvas>
</body>
</html>
更新:答案是:
在上面的代码中,我错误地假设getTimeout
函数是同步的,即我预计,在调用它时程序执行将停止,等待 1000 毫秒,然后调用 ,然后draw_next_image
才执行ctx.clearRect
。
实际上,Javascript 不是那样工作的。实际上getTimeout
是异步的,即getTimeout
设置一个 Timeout 并几乎立即返回并且代码继续执行,因此它ctx.clearRect
被立即调用并且实际上在draw_next_image
. 因此,到 Timeout 到期并调用draw_next_image
时,代码的执行可能会到达任意行代码。在我的情况下,所有 4clearRect
将几乎同时被调用,早在超时到期之前。然后 1000 毫秒后,所有 4 个超时将几乎一个接一个地立即到期,并且所有 4 个图像也将几乎同时绘制,没有clearRects
,这在很久以前就已经执行了。