Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.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 为什么下面的JS函数会破坏浏览器进程?_Javascript - Fatal编程技术网

Javascript 为什么下面的JS函数会破坏浏览器进程?

Javascript 为什么下面的JS函数会破坏浏览器进程?,javascript,Javascript,我知道已经有很多帖子讨论了为什么不尝试在Javascript中实现wait()或sleep()函数。所以,这不是为了使它能够用于实现目的,而是为了概念验证而使它能够工作 尝试 var wait = function (milliseconds) { var returnCondition = false; window.setTimeout(function () { returnCondition = true; }, milliseconds); while (!re

我知道已经有很多帖子讨论了为什么不尝试在Javascript中实现
wait()
sleep()
函数。所以,这不是为了使它能够用于实现目的,而是为了概念验证而使它能够工作

尝试

var wait = function (milliseconds) {
    var returnCondition = false;
    window.setTimeout(function () { returnCondition = true; }, milliseconds);
    while (!returnCondition) {};
};
冻结我的浏览器。为什么
wait()
似乎永远不会结束

编辑:感谢您迄今为止的回答,我不知道while循环从不允许执行任何其他代码

那么,这行得通吗

console.log("Starting...");wait(3000);console.log("...Done!");

JavaScript在单个线程中执行。只有当一个执行路径退出时,另一个执行路径才能开始。因此,当您启动
wait(3000)
时,会发生以下情况:

  • returnCondition
    设置为
    false
  • 已计划超时
  • 无限循环开始
每个
标记、每个正在处理的事件以及每个超时(对于浏览器,还有UI刷新)都会启动一个单独的执行路径。因此,不保证3000毫秒的超时时间在3000毫秒内运行,而是在3000毫秒后发动机“空闲”时的任何时间运行

wait
函数永远不会退出,因此脚本的执行路径永远不会结束,计划的超时也永远不会到来

编辑:

这意味着,一旦一个
标记开始,或者Node.js开始执行一个JavaScript文件,执行必须在其他任何事情发生之前到达底部。如果某个函数是由于某个事件或超时而启动的,则该函数需要在其他任何事情发生之前退出

var wait = function (milliseconds) {
    var returnCondition = false;
    var setMyTimeOut = true;
    while (!returnCondition) {
        if (setMyTimeOut) {
            window.setTimeout(function() { returnCondition = true; }, milliseconds);
            setMyTimeOut = false;
        }
    };
    return;
};

log(“脚本顶部”);
函数theTimeout(){
日志(“超时顶部”);
//长的东西
日志(“超时底部”);
}
设置超时(超时,0);
设置超时(超时,0);
log(“脚本底部”);

这里有三条执行路径。第一个是
标记:它从打印“scripttop”开始,安排两个超时(用于“立即”),然后打印“scriptbottom”,然后到达
的末尾,解释器处于空闲状态。这意味着它有时间执行另一个执行路径,并且有两个超时正在等待,因此它选择其中一个并开始执行它。当它正在执行时,其他任何东西也不能执行(甚至UI更新);另一个超时,即使它也被安排在“立即”,也要等待第一个超时的执行路径结束。当它这样做时,第二个超时就来了,它也会被执行。

JavaScript是单线程的。调用setTimeout时,将作为参数传入的方法放入异步调用堆栈。这意味着块中的下一行代码将在setTimeout调用之后立即执行,而作为参数传入的函数将在wait方法退出后执行

while循环正在等待一个条件,该条件在wait函数运行时永远不会发生,因为设置您的标志的函数在wait函数完成之前不会运行

实施等待的正确方法是:

<script>
  console.log("script top");
  function theTimeout() {
    console.log("timeout top");
    // something long
    console.log("timeout bottom");
  }
  setTimeout(theTimeout, 0);
  setTimeout(theTimeout, 0);
  console.log("script bottom");
</script>
这里传入一个回调函数,该函数将在超时后执行

如果有多个异步样式调用,则可以使用承诺。承诺将使您的代码易于阅读,并且可以轻松地将多个异步调用链接在一起。有非常好的promise库管理员:JQuery内置了$.Deferred,但如果您正在编写node.js代码,则可以使用Q

promise样式的实现如下所示:

var wait = function (milliseconds, onEnd) {

    window.setTimeout(function () { onEnd(); }, milliseconds);

};

wait(1000, function(){alert('hi')});

下面这本书帮助我理解了这个主题:

异步JavaScript:Trevor Burnham用更少的代码构建响应更快的应用程序

Javascript是单线程的,通过while循环,您将阻止任何其他代码执行。。。这就是线程被锁定时超时不起作用的主要原因,它看起来应该是这样的。我不清楚您是否需要
wait()
函数。你几乎肯定做错了™@MadaraUchiha:“几乎”?:)回应编辑:不,它不起作用。同样,在当前执行路径中,您永远不会将
returnCondition
设置为
true
,因此您将以无限循环结束。无论您是从循环内部还是从循环外部安排超时;在脚本的最后一行完成之前,它不会执行。我理解,至少部分理解。如果我在while循环中设置一次超时会怎么样?如果你在无限循环中启动超时,你会非常快地消耗掉内存。我没有足够的勇气去尝试看看Chrome是否真的会很快中止它,或者我的计算机是否会首先在一堆可怜的磁盘交换中崩溃。所以即使你在while循环中调用setTimeout,它的回调仍然只会在while循环结束时执行?你是在告诉浏览器,3秒钟后它应该在空闲时执行你的函数。
var wait = function (milliseconds) {

    var onEnd = null;

    window.setTimeout(function () { onEnd(); }, milliseconds);

    return {

    then: function(action){
            onEnd = action;
    }

    }
};

wait(1000).then(function(){alert('hi')});