加载功能导致网站停滞

时间:2016-05-26 21:34:10

标签: javascript function while-loop settimeout

当我尝试通过按's'然后按'l''加载''保存的图形'时,它会导致浏览器停止响应。我认为这是因为所有的while循环(第47行和更高),但即使是我添加的setTimeout事情也没有帮助。非常感谢帮助。 此脚本嵌入在我的网站(https://veryblankwhitepaper.weebly.com/with-canvas.html)中:

var canvas = document.getElementById("draw");
var context = canvas.getContext("2d"); 
var color = "#0000ff";
var xs = [];
var ys = [];
var colors = [];
var sizes = [];
var loadDrawing = function(){
    for(var p = 0; p < xs.length; p++){
        setTimeout(function(){
            context.beginPath();
            context.moveTo(xs[p], ys[p]);
            context.fillStyle = colors[p];
            context.arc(xs[p] - (sizes[p] / 2), ys[p] - (sizes[p] / 2), sizes[p], 0, Math.PI * 2);
            context.fill();
            context.closePath();
        },10);
    }
    alert("done!");
}
var isMouseDown = false; var thickness = 4;
function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
} 
window.onkeyup = function(e){
    e = e || e.which; 
    var key = e.which || e.keycode; 
    if(key === 65){
    color = prompt("Change the color");
    } 
    if(key === 76){
        if(confirm("Do you want to load a saved picture?") === true){
            var load = prompt("What file do you want to load","insert saved file name here");
            context.clearRect(0,0,100000,100000);
            alert("please wait. this may take some time depending on how big the drawing is..");
            xs = [];
            ys = [];
            colors = [];
            sizes = [];
            var int = 0;
            var str = "";
            while(localStorage[load + "xs"][int] !== ""){
                while(localStorage[load + "xs"][int] !== ","){
                    setTimeout(function(){
                        str = str + localStorage[load + "xs"][int];
                        int = int + 1;
                    },10);
                }
                int = int + 1; 
                xs.push(str);
                str = "";
            }
            int = 0;
            while(localStorage[load + "ys"][int] !== ""){
                while(localStorage[load + "ys"][int] !== ","){
                    setTimeout(function(){
                        str = str + localStorage[load + "ys"][int];
                        int = int + 1;
                    },10);
                }
                int = int + 1; 
                ys.push(str);
                str = "";
            }
            int = 0;
            while(localStorage[load + "colors"][int] !== ""){
                while(localStorage[load + "colors"][int] !== ","){
                    setTimeout(function(){
                        str = str + localStorage[load + "colors"][int];
                        int = int + 1;
                    },10);
                }
                int = int + 1; 
                colors.push(str);
                str = "";
            }
            int = 0;
            while(localStorage[load + "sizes"][int] !== ""){
                while(localStorage[load + "sizes"][int] !== ","){
                    setTimeout(function(){
                        str = str + localStorage[load + "sizes"][int];
                        int = int + 1;
                    },10);
                }
                int = int + 1; 
                sizes.push(str);
                str = "";
            }
            loadDrawing();
        }
    }
    if(key === 83){
        if(confirm("Do you want to save the drawing?") === true){
            var answer = prompt("Enter a name for the drawing.");
            localStorage[answer + "xs"] = xs;
            localStorage[answer + "ys"] = ys;
            localStorage[answer + "colors"] = colors;
            localStorage[answer + "sizes"] = sizes;
        }
    }
    if(key === 66){
        thickness = prompt("change thinkness (in pixels)");
    }
    if(key === 67){
        if(confirm("clear the canvas?") === true){
            context.clearRect(0,0,10000,10000);
       }
   }
}
window.onmousedown = function() {
    isMouseDown = true;
}
window.onmouseup = function () {
    isMouseDown = false;
}
window.onmousemove = function(e) {
    if(isMouseDown === true){
        xs.push(getMousePos(canvas, e).x);
        ys.push(getMousePos(canvas, e).y);
        colors.push(color);
        sizes.push(thickness);
        context.beginPath();
        context.moveTo(getMousePos(canvas, e).x, getMousePos(canvas, e).y);
        context.fillStyle = color;
        context.arc(getMousePos(canvas, e).x - (thickness / 2), getMousePos(canvas, e).y - (thickness / 2), thickness, 0, Math.PI * 2);
        context.fill();
        context.closePath();
    }
}

1 个答案:

答案 0 :(得分:0)

建议的新代码

看来你的两个while循环只是试图将逗号分隔的字符串分解为其分离的部分并将结果放入数组中。如果情况确实如此(您在问题中尚未描述的内容),那么您可以这样做:

xs = localStorage[load + 'xs'].split(",");

所以,如果你有一个如下所示的输入字符串:

"aaa,bbb,ccc,ddd"

您将获得如下输出数组:

["aaa","bbb","ccc","ddd"]

如果您有不同的输入或期望不同的输出,那么请完整地向我们展示示例输入和输出的样子。试图对有缺陷的代码进行逆向工程使得很难弄清楚代码的实际意图是什么。

解释当前代码的错误

你现在拥有的while循环代码存在根本缺陷并导致无限循环。

       while(localStorage[load + "xs"][int] !== ""){
            while(localStorage[load + "xs"][int] !== ","){
                setTimeout(function(){
                    str = str + localStorage[load + "xs"][int];
                    int = int + 1;
                },10);
            }
            xs.push(str);
            str = "";
        }

问题是这个。 Javascript是一种事件驱动的语言。当您安排setTimeout()时,它会向系统注册一个计时器,当该计时器触发时,它会将您的计时器回调放入Javascript事件队列中。只有当Javascript的主线程完成时才会处理该事件。

在您的特定情况下,您的while循环只是疯狂地旋转,intsetTimeout()运行之前不会增加。但是setTimeout()循环结束前while无法运行。因此,由于两个都在等待另一个并且while循环正在旋转占用主JS线程,所以你得到一个无限循环。这种类型的结构在Javascript中无法工作。