Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 调试冻结浏览器的长时间运行脚本_Javascript - Fatal编程技术网

Javascript 调试冻结浏览器的长时间运行脚本

Javascript 调试冻结浏览器的长时间运行脚本,javascript,Javascript,假设我有一个长时间运行的JavaScript进程,可以通过单击 按钮一旦运行,它就会冻结浏览器。该过程由一个长循环组成 这会重复一些工作负载,其中一次迭代花费的时间相对较少。这是 这种“循环式”流程的精简版本: <html> <head> <script> var Process = function(start) { this.start = start; } Process

假设我有一个长时间运行的JavaScript进程,可以通过单击 按钮一旦运行,它就会冻结浏览器。该过程由一个长循环组成 这会重复一些工作负载,其中一次迭代花费的时间相对较少。这是 这种“循环式”流程的精简版本:

<html>

<head>
    <script>
        var Process = function(start) {
            this.start = start;
        }

        Process.prototype.run = function(stop) {
            // Long-running loop
            for (var i = this.start; i < stop; i++) {
                // Inside the loop there is some workload which 
                // is the code that is to be debugged
                console.log(i);
            }
        }

        var p = new Process(100);

        window.onload = function() {
            document.getElementById("start").onclick = function() {
                p.run(1000000000);
            }
        }
    </script>
</head>

<body>
    <input id="start" type="button" value="Start" />
</body>

</html>

var过程=功能(启动){
this.start=start;
}
Process.prototype.run=函数(停止){
//长循环
for(var i=this.start;i
由于浏览器冻结,调试类似循环的脚本并不容易。避免浏览器冻结的另一种方法是使用web worker。这种方法的缺点是web工作人员的调试能力差:不支持Firebug之类的工具


在维护可调试性的同时,有没有办法避免浏览器冻结?如果是,则可以调试脚本,直到脚本稳定并委托给web工作人员进行生产

事实证明有一种方法可以实现这一点。使用队列数据结构 (例如),一个间隔计时器和一些小的 对原始流程控制流的修改可以构建一个不需要修改的GUI 冻结浏览器,使流程完全可调试,甚至允许附加功能 比如脚步、停顿和停止

事情是这样的:

<html>

<head>

    <script src="http://code.stephenmorley.org/javascript/queues/Queue.js"></script>
    <script>
        // The GUI controlling process execution
        var Gui = function(start) {
            this.timer = null; // timer to check for inputs and/or commands for the process
            this.carryOn = false; // used to start/pause/stop process execution
            this.cmdQueue = new Queue(); // data structure that holds the commands 
            this.p = null; // process instance
            this.start = start;
            this.i = start; // input to the modified process 
        }

        Gui.prototype = {
            /**
             * Receives a command and initiates the corresponding action 
             */
            executeCmd: function(cmd) {
                switch (cmd.action) {
                    case "initialize":
                        this.p = new Process(this);
                        break;
                    case "process":
                        this.p.run(cmd.i);
                        break;
                }
            },

            /*
             * Places next command into the command queue
             */
            nextInput: function() {
                this.cmdQueue.enqueue({
                    action: "process",
                    i: this.i++
                });
            }
        }

        // The modified loop-like process
        var Process = function(gui) {
            this.gui = gui;
        }

        Process.prototype.run = function(i) {
            // The workload from the original process above
            console.log(i);

            // The loop itself is controlled by the GUI
            if (this.gui.carryOn) {
                this.gui.nextInput();
            }
        }

        // Event handlers for GUI interaction
        window.onload = function() {

            var gui = new Gui(100);

            document.getElementById("init").onclick = function() {
                gui.cmdQueue.enqueue({ // first command will instantiate the process
                    action: "initialize"
                });

                // Periodically check the command queue for commands
                gui.timer = setInterval(function() {
                    if (gui.cmdQueue.peek() !== undefined) {
                        gui.executeCmd(gui.cmdQueue.dequeue());
                    }
                }, 4);
            }

            document.getElementById("step").onclick = function() {
                gui.carryOn = false; // execute just one step
                gui.nextInput();
            }

            document.getElementById("run").onclick = function() {
                gui.carryOn = true; // (restart) and execute until further notice
                gui.nextInput();
            }

            document.getElementById("pause").onclick = function() {
                gui.carryOn = false; // pause execution
            }

            document.getElementById("stop").onclick = function() {
                gui.carryOn = false; // stop execution and clean up 
                gui.i = gui.start;
                clearInterval(gui.timer)

                while (gui.cmdQueue.peek()) {
                    gui.cmdQueue.dequeue();
                }
            }
        }
    </script>
</head>

<body>
    <input id="init" type="button" value="Init" />
    <input id="step" type="button" value="Step" />
    <input id="run" type="button" value="Run" />
    <input id="pause" type="button" value="Pause" />
    <input id="stop" type="button" value="Stop" />
</body>

</html>

//控制流程执行的GUI
var Gui=函数(启动){
this.timer=null;//检查进程输入和/或命令的计时器
this.carryOn=false;//用于启动/暂停/停止进程执行
this.cmdQueue=new Queue();//保存命令的数据结构
this.p=null;//进程实例
this.start=start;
this.i=start;//修改进程的输入
}
Gui.prototype={
/**
*接收命令并启动相应的操作
*/
executeCmd:函数(cmd){
开关(指令动作){
案例“初始化”:
p=新工艺(本);
打破
案例“过程”:
这个.p.run(cmd.i);
打破
}
},
/*
*将下一个命令放入命令队列
*/
nextInput:function(){
this.cmdQueue.enqueue({
行动:“进程”,
i:这个,我++
});
}
}
//改进的类环过程
var进程=函数(gui){
this.gui=gui;
}
Process.prototype.run=函数(i){
//来自上述原始流程的工作负载
控制台日志(i);
//循环本身由GUI控制
if(this.gui.carryOn){
this.gui.nextInput();
}
}
//GUI交互的事件处理程序
window.onload=函数(){
var gui=新gui(100);
document.getElementById(“init”).onclick=function(){
gui.cmdQueue.enqueue({//first命令将实例化该进程
操作:“初始化”
});
//定期检查命令队列中的命令
gui.timer=setInterval(函数(){
if(gui.cmdQueue.peek()!==未定义){
executeCmd(gui.cmdQueue.dequeue());
}
}, 4);
}
document.getElementById(“步骤”).onclick=function(){
gui.carryOn=false;//只执行一个步骤
gui.nextInput();
}
document.getElementById(“run”).onclick=function(){
gui.carryOn=true;//(重新启动)并执行,直到另行通知
gui.nextInput();
}
document.getElementById(“暂停”).onclick=function(){
gui.carryOn=false;//暂停执行
}
document.getElementById(“停止”).onclick=function(){
gui.carryOn=false;//停止执行并清理
gui.i=gui.start;
clearInterval(gui.timer)
while(gui.cmdQueue.peek()){
gui.cmdQueue.dequeue();
}
}
}
虽然这种方法肯定不适合人们所能想到的所有长时间运行的脚本,但它确实适用 可以适应任何类似循环的场景。我用它来移植人造血管
智能算法到浏览器。

请删除问题部分。我的意思是,在这个回答中我不确定,你回答了你的问题,这很好,但是你的问题和你的答案之间的间隔大约是1分钟,所以我想你是想分享一些信息来调试这些长时间运行的脚本?@fuyushimoya是的,是的。实现监控的事情还是有点复杂,不管怎样,我会投你赞成票的。