考虑这个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如何阻止这里?
有人可以向我解释一下吗?
答案 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
用例而不阻塞主线程。