为何Canvas代码中的setInterval无法每秒执行generateGame函数?
问题分析与解决方案
嘿,这问题我太熟了!你的setInterval只执行一次的核心原因是你传错参数给定时器了——你直接调用了generateGame(c, drwMthd),而不是把函数本身传给setInterval。
为什么原代码失效?
setInterval的第一个参数需要是一个函数引用(也就是函数名,或者一个匿名函数),这样定时器才能每隔指定时间去调用这个函数。但你写的setInterval(generateGame(c, drwMthd), 1000)会立刻执行generateGame函数,然后把它的返回值(这里是undefined,因为函数没有return语句)传给setInterval。定时器拿到undefined后,根本没法重复触发任何逻辑,所以你只会看到一次reset、all cleared和all drawn的输出。
两种修正方案
方案1:用匿名函数包裹调用
把generateGame的调用放在一个箭头函数里,这样setInterval拿到的是一个函数引用,每隔1秒才会执行这个箭头函数,进而调用generateGame:
buildCanvas(); function buildCanvas(){ let c = document.getElementById('myCanvas'); let drwMthd = c.getContext('2d'); // 用箭头函数包裹,传递函数引用 setInterval(() => generateGame(c, drwMthd), 1000); function generateGame(c, drwMthd){ refreshC(c, drwMthd); drawObjects(drwMthd); console.log('reset'); } } // 其他函数保持不变 function refreshC(c, drwMthd){ drwMthd.clearRect(0, 0, c.width, c.height); console.log('all cleared'); } function drawObjects(drwMthd){ boxGenerator(10, 10, 10, 10, "green", drwMthd); boxGenerator(1, 1, 10, 10, "green", drwMthd); console.log('all drawn'); } function boxGenerator(top, left, width, height, color, drwMthd){ drwMthd.fillStyle = color; drwMthd.fillRect(top, left, width, height, color); }
方案2:利用作用域省略参数传递
因为generateGame定义在buildCanvas内部,它可以直接访问外层作用域的c和drwMthd变量,所以不需要额外传参,直接把函数名传给setInterval就行,代码更简洁:
buildCanvas(); function buildCanvas(){ let c = document.getElementById('myCanvas'); let drwMthd = c.getContext('2d'); // 直接传递函数引用,无需传参 setInterval(generateGame, 1000); function generateGame(){ refreshC(c, drwMthd); drawObjects(drwMthd); console.log('reset'); } } // 其他函数保持不变 function refreshC(c, drwMthd){ drwMthd.clearRect(0, 0, c.width, c.height); console.log('all cleared'); } function drawObjects(drwMthd){ boxGenerator(10, 10, 10, 10, "green", drwMthd); boxGenerator(1, 1, 10, 10, "green", drwMthd); console.log('all drawn'); } function boxGenerator(top, left, width, height, color, drwMthd){ drwMthd.fillStyle = color; drwMthd.fillRect(top, left, width, height, color); }
验证效果
修正后,你会看到控制台每秒输出一次all cleared、all drawn和reset,Canvas也会每秒清屏并重新绘制方块,实现你想要的刷新率控制。
内容的提问来源于stack exchange,提问作者Ghoyos
相关产品推荐
相关产品推荐

