为什么不阻止JavaScript?

时间:2011-08-10 14:05:29

标签: javascript

考虑这个JavaScript代码:

<script type="text/javascript">

function loop(Message){
document.getElementById('output').innerHTML = 
document.getElementById('output').innerHTML + Message + '</br>';
}

window.setInterval("loop('Message1')", 1000); //Prints "Message1" every 1 Seconds
window.setInterval("loop('Message2')", 3000); //Prints "Message2" every 3 Seconds

</script>

<body>
<div id="output"></div>
</body>

Output:
Message1
Message1
Message2
Message1
Message1
Message1
Message2
...

现在考虑一下这个PHP代码:

<?php
while(true){               // Print "Message1" every 1 Second
echo 'Message 1 </br>';
sleep(1);
}



while(true){              //This Code will never be executed, 
echo 'Message 2 </br>';    //because the First Loop Blocks the Process!!!!!
sleep(3);
}

?>

Output:
Message1
Message1
Message1
Message1
Message1
Message1
...

为什么第一个JavaScript循环不像PHP中的第一个while-Loop那样停止整个过程?

我知道Javascript是SingleThreaded,所以我想,JavaScript不能只是启动一个新线程来处理第二个循环。所以我想知道JavaScript如何阻止这里?

有人可以向我解释一下吗?

6 个答案:

答案 0 :(得分:6)

因为setInterval具体不是 sleep

setInterval更像是一个调度程序。它标志着应该执行某些事情的时间,让主线程完全忘记它,直到那个时间到来。

另一方面,

sleep基本上是一个无操作循环,它在循环时不允许任何其他操作。

这很重要,因为PHP和Javascript的用例完全不同。 PHP脚本具有开始和结束,并以线性方式执行。 Javascript用于交互性,这意味着它需要以非线性方式响应各种事物(鼠标点击,键盘输入,定时器,AJAX回调)。如果主线程被阻塞等待计时器,则不会发生任何事情,界面将显示为冻结。

这是jQuery的John Resig关于Javascript计时器的好文章:http://ejohn.org/blog/how-javascript-timers-work/

答案 1 :(得分:1)

由于JavaScript是单线程的,因此只有堆栈上有要执行的命令。每次调用setInterval时,函数都将被放入堆栈,并在执行所有先前的函数时执行。当您有大量数据要编译但希望ui不被阻止用户输入时,这非常有用。 但是当你使用JavaScripts时,它会像php一样具有相同的阻塞效果

答案 2 :(得分:1)

以前的答案没问题,但我还有一些事要补充。也许这会对你有所帮助。

PHP中的JavaScript代码如下所示:

<?php
function loop($message, $duration, $multiplier){
    while($multiplier--){
        echo $message;
        sleep($duration);
    }
}
while(true){
    loop("Message1", 1, 2);
    loop("Message2", 1, 1);
}
?>

但是你必须记住之前帖子中的内容(在一个PHP脚本中一次只能输入一个命令)。

答案 3 :(得分:0)

因为你没有写过任何循环。

您刚刚注册了一些应该以指定间隔运行的代码。

因此,每隔一秒loop使用参数'Message1'执行一次,并且每3秒执行一次,使用参数'Message3'执行。但是,由于每次调用返回的速度非常快,因此在第一次调用之后运行另一个调用就不会有任何问题。

答案 4 :(得分:0)

您没有使用javascript while循环。

您使用的是setInterval

的功能

他们是不同的。

以下是js while循环的更多内容:http://en.wikipedia.org/wiki/JavaScript_syntax#While_loop

答案 5 :(得分:0)

Javascript,单线程,无法阻止。如果是这样,整个浏览器活动(点击,渲染等)将停止等待某事发生。

这就是为什么昂贵的操作(比如ajax请求)使用回调机制来处理响应的原因。

现在,您的特定示例setInterval按设计方式工作(如setTimeout)。他们处理sleep用例而不阻塞主线程。