我想在具有一定间隔的画布上绘制并且setTimeout不起作用

时间:2011-05-01 17:53:01

标签: javascript html5 settimeout

以下是重要的代码部分:

function drawCircle(i, color1, color2) {
            var ctx = canvas.getContext("2d");
            if (i % 2 == 1) {
                ctx.fillStyle = color1;
            }
            else {
                ctx.fillStyle = color2;
            }
            ctx.beginPath();
            ctx.arc(110, 270, 10, 0, Math.PI * 2, true);
            ctx.closePath();
            ctx.fill();
        }
for (var i = 0; i < 10; i++) {
    setTimeout(drawCircle(i, color2, color5), 4000);
}

请注意,在我在较大的项目中使用与此类似的代码之前,这只是我想要尝试的一个片段。这不能正常工作,图像只绘制一次,也就是说,我只看到绘制的最后一个圆圈。我已经用谷歌搜索了这个,但到目前为止没有任何帮助我。

3 个答案:

答案 0 :(得分:4)

您要使用的是setIntervalsetTimeout只会触发一次事件。他们有相同的参数列表。

此外,我不认为您使用setTimeout的方式是正确的。你现在写的方式,在实际传递任何内容到setTimeout / setInterval之前触发了该函数。所以你应该写:

setInterval(function() {              // GOOD. An actual function is passed 
    drawCircle(...);                  // as the first argument.
}, 4000);

或:

setInterval('drawCircle(...)', 4000); // GOOD. the JS statement is supplied as 
                                      // a string and later on will be evaluated 
                                      // and executed with eval().

setInterval(drawCircle(...), 4000);   // BAD! drawCircle() is fired, its result 
                                      // evaluated and passed on to setInterval 
                                      // that doesn't know what to do with it.

修改

您在JavaScript中没有任何阻止例程。它是一种单线程,事件驱动的语言。如果你打电话给setInterval之类的东西,它会立即成功。仅在4秒左右后才会调用您的回调函数。然而,与此同时,JS将忙于做各种不同的事情 - 例如对用户生成的其他事件做出反应。你想要做的是调用setTimeout一次,然后在回调函数内部,就在返回之前再次使用相同的函数和一组i的不同参数调用它。这些方面的东西:

function drawCircle(i, ...) {

    // ... do stuff ...

    if (i < 10) {                    // Check if the callback has been invoked 10 
                                     // times already.
        setTimeout(function() {      // Schedule the callback for execution
            drawCircle(i + 1, ...);  // again after anoter 4 seconds.
        }, 4000);
    }
}

setTimeout(function() {              // Invoke the callback the first time 
    drawCircle(1, ...);              // after first 4 seconds.
}, 4000);

答案 1 :(得分:1)

这里的问题是你连续多次调用setTimeout,而不是从回调中再次调用它。尝试将调用移至setTimeoutdrawCircle函数的末尾以查看动画。

答案 2 :(得分:1)

实际上有一些事情会导致您的代码行为异常,而且他们的所有循环都是如此。第一个问题是调用setTimeout,主要是因为你没有将函数对象作为第一个参数传递给它,大多数人会通过这样做来解决这个问题:

for (var i = 0; i < 10; i++) {
    setTimeout(function() {
        drawCircle(i, color2, color5);
    }, 4000);
}

这将导致setTimeout按预期延迟,但它最终将调用drawCircle,其中10为第一个参数10次,这是因为每次调用都使用相同的引用#34; i&# 34;变量。在调用完成之前,i的值不会被检索...在循环完成后4秒左右,当我已经是10时。

要解决这个问题,您还需要一个功能:

function getDrawer(i, color2, color5) {
    return function() {
        drawCircle(i, color2, color5);
    }
}

for (var i = 0; i < 10; i++) {
    setTimeout(getDrawer(i, color2, color5), 4000);
}

立即调用getDrawer(一个可怕的名字,请不要使用它)函数,因此立即访问i的值并由getDrawer返回的匿名函数记住。该匿名函数将由setTimeout调用。