今天在实现某些动画功能的时候,尝试着在while中调用setTimeout()函数,并在其中递增判断数值,满以为能够执行下去,但是却发现最后系统崩溃了。
<span style="font-size:14px;">a = 0;
while( a < 1){
setTimeout(function(){
target.style.opacity = a;
}, 250);
}</span>
经过排查,终于发现了原因:
JavaScript的引擎是一个单线程执行的。不同于其他多线程的引擎,在while执行的时候,会一直判断条件。因为a < 1一直为真,所以while一直在执行。而setTimeout需要250ms才能执行,与JS执行while代码相比,实在是来不及。于是,因为while已经在250ms内不停的调用了很多次内部代码,而setTimeout函数并不能执行。因此,系统的内存不够用了,于是崩溃了。
我们可以通过下面的测试来证明:
<span style="font-size:14px;"> var a = 0;
while(a < 0){
setTimeout(function(){
alert("1");
a++;
}, 2000);
}
setTimeout(function(){alert("2")}, 1000);
setTimeout(function(){alert("3")}, 100);
alert("4");</span>
执行的结果是:弹出4,弹出3,弹出2,然后内存不断上升,最终系统崩溃。
由此可见,在while中添加setTimeout函数,是不可行的。
在此,我从网络上看到了一个解决方法:
(源于:http://zhidao.baidu.com/link?url=kxVjA7Tr0SeQUn9m-PBOzgPaQys07tDhlxLHBTdc80VJDjYbtEJItnjdeyZArZsAT2qzqkUbt9HWTRkG6uMjoA-kBFv2oq8osiRrYN3EKyO)
将setTimeout函数嵌套在另一个setTimeout函数内:
<span style="font-size:14px;">var i=0;
setTimeout(function(){
alert("i="+i++);
if(i != 3){
setTimeout(arguments.callee,3000);
}
},3000);</span>
如此一来,就不会发生崩溃现象了。
!补充:
经过再次测试和实践,发现一开始所想的,使用setTimeout是不好的。while + setTimeout 组合非常失败,更佳的组合应该为:
setInterval + if 语句。
执行setInterval后,相当于每次都会再次调用setTimeout函数。然而在函数内部,所应执行的代码不应该是while之类的循环,因为setInterval已经实现了隔一段时间循环一次的功能了。这时候,我们应该通过if语句判断,这样即可。