我编写了一个分形图像生成器,它的运行时间从几分之一秒到几分钟不等,具体取决于每个像素的迭代次数。在当前版本中,用户必须等待图像完全渲染,直到他可以看到结果。在此期间,浏览器 UI 被阻止,Firefox 将每 10 秒显示一条警告消息,询问脚本是否应该继续、调试或停止。
问题:是否可以在脚本运行时显示画布内容的更新?
我编写了一个分形图像生成器,它的运行时间从几分之一秒到几分钟不等,具体取决于每个像素的迭代次数。在当前版本中,用户必须等待图像完全渲染,直到他可以看到结果。在此期间,浏览器 UI 被阻止,Firefox 将每 10 秒显示一条警告消息,询问脚本是否应该继续、调试或停止。
问题:是否可以在脚本运行时显示画布内容的更新?
是的
UI 被阻塞,直到当前调用(通常由事件启动)返回。当函数返回对 DOM 的任何更改时,将更新下一个事件(如果有的话)将被放置在调用堆栈上并被调用,否则 javascript 引擎只会等待一个事件。
您可以使用 setTimeout 来安排事件,处理一些像素,再次设置超时退出等等。
仅就逻辑流程而言的示例
var complete = false;
var pixels = 100000;
var pixelsPerCall = 1000;
function addPixels(){
// process x number of pixels
var i = pixelsPerCall;
while(i-- && pixels--){
// do a pixel
}
if(pixels === 0){
complete = true;
}
if(! complete){
setTimeout(addPixels,0);
}
}
addPixels();
尽管对于这种类型的应用程序,您最好使用 webWorkers。根据机器拥有的内核数量,您可以获得吞吐量的巨大增加。例如,具有 8 个内核的 I7 CPU 将完成工作的速度大约是 8 倍。此外,网络工作者不会阻塞 DOM,因此可以运行任意时间。
一种可能的方法是将计算分成块,使用setTimeout
/运行每个步骤setImmediate
,更新画布并运行另一个块。
这不仅会逐步更新画布,还会阻止浏览器抱怨长时间运行的脚本。