Javascript 强制从递归函数重新绘制画布

Javascript 强制从递归函数重新绘制画布,javascript,jquery,html,canvas,Javascript,Jquery,Html,Canvas,我想创建一个自定义进度条。但我正在使用一个递归函数来更新它的数据,我不能更新进度条中的画布 以下是我的部分代码: var length = 0; recursiveFunction = function(){ length++; updateLength(length); //some work recursiveFunction(); } updateLength = function(length){ setLength(length); } setLen

我想创建一个自定义进度条。但我正在使用一个递归函数来更新它的数据,我不能更新进度条中的画布

以下是我的部分代码:

var length = 0;

recursiveFunction = function(){
   length++;
   updateLength(length);
   //some work
   recursiveFunction();
}

updateLength = function(length){
   setLength(length);
}

setLength(length){
    var c = document.getElementById(canvas);
    var ctx = c.getContext("2d");
    ctx.fillStyle = "#fc0";
    ctx.fillRect(0, 0, length, 10);
}
所有这些函数都位于不同的JS文件和不同的类中


问题是canvas不能在
setLength
函数中重画

这与JavaScript是单线程的有关,一次只能做一件事。只要代码正在运行,其他一切(如更新到屏幕)都必须等待

为了避免这种情况,您可以在代码中引入一些异步性,将代码暂停到允许更新屏幕的程度

例如(注意:如果不执行其他更改,仅此更改可能不起作用):

该函数现在将结束,但添加了一个事件以供将来使用(在这种情况下通常为16.7ms)。同时,画布可以更新到屏幕

但当然也不是没有问题。上下文正在更改,因为它是一个递归函数,所以您可能希望传入参数。虽然没有在文章中显示哪些参数(如果有的话),但是您可以使用允许传入参数的
setTimeout()
来代替
requestAnimationFrame()
。如果您依赖于上下文(即
),也可以使用
bind()

比延迟更重要的是:

setTimeout(recursiveFunction.bind(this), 17, arg1, arg2, arg3, ...);

另一种方法是使用。这将允许您在一个单独的线程上尽可能快地运行代码,并偶尔向主主机发送一条消息,其中包含到目前为止的进度,这将允许独立地更新画布。如果功能长期运行,则这是建议的路径。Web工作者已经但不会使用旧版IE或Opera Mini。

这与JavaScript是单线程的有关,一次只能做一件事。只要代码正在运行,其他一切(如更新到屏幕)都必须等待

为了避免这种情况,您可以在代码中引入一些异步性,将代码暂停到允许更新屏幕的程度

例如(注意:如果不执行其他更改,仅此更改可能不起作用):

该函数现在将结束,但添加了一个事件以供将来使用(在这种情况下通常为16.7ms)。同时,画布可以更新到屏幕

但当然也不是没有问题。上下文正在更改,因为它是一个递归函数,所以您可能希望传入参数。虽然没有在文章中显示哪些参数(如果有的话),但是您可以使用允许传入参数的
setTimeout()
来代替
requestAnimationFrame()
。如果您依赖于上下文(即
),也可以使用
bind()

比延迟更重要的是:

setTimeout(recursiveFunction.bind(this), 17, arg1, arg2, arg3, ...);

另一种方法是使用。这将允许您在一个单独的线程上尽可能快地运行代码,并偶尔向主主机发送一条消息,其中包含到目前为止的进度,这将允许独立地更新画布。如果功能长期运行,则这是建议的路径。网络工作者已经但不会使用旧版IE或Opera Mini。

requsetAnimationFrame
首先没有帮助我。我使用了
closures
setTimeout
来释放线程。也许现在,
requsetAnimationFrame
可以帮助我,但它没有它就可以工作,所以…
requsetAnimationFrame
首先没有帮助我。我使用了
closures
setTimeout
来释放线程。也许现在,
requsetAnimationFrame
可以帮助我,但它在没有它的情况下工作,所以。。。
setTimeout(recursiveFunction.bind(this), 17, arg1, arg2, arg3, ...);