你有没有需要在JavaScript中使用sleep命令?通常情况下,可以使用现有的setTimeout(),clearTimeout()和setInterval()来完成,在这种情况下,你应该使用内置函数。但如果你真的需要有选项的sleep或等待语句,看看什么代码可以工作得最好。
sleep方法有什么要求呢?看看下面的权威描述最能说明问题:
暂停应用程序的当前线程,时间为指定的毫秒数,允许其他进程(或线程)继续运行。
下面是javascript实现sleep函数的各种方法:
(1)通过循环实现JavaScript sleep
(2)通过Java Applet实现JavaScript sleep
(3)通过Flash实现JavaScript sleep
(4)通过XMLHttp实现JavaScript sleep
通过循环实现JavaScript sleep
代码如下:
1
2
3
4
5
6
7
|
<script type=
"text/javascript"
>
// bad implementation
function sleep(milliSeconds){
var startTime =
new
Date().getTime();
// get the current time
while
(
new
Date().getTime() < startTime + milliSeconds);
// hog cpu
}
</script>
|
我们使用一个while循环,在第3行,不断检测当前的时间,到时间了我们就停止循环。这个循环运行速度很快,浏览器将占用所有宝贵的CPU资源。检查时间可能看起来并不多,但每秒做数千次(或几万),使您的计算机上性能受到影响。
通过Java Applet实现JavaScript sleep
这个解决方案是插入一个Java Applet,通过Javascript和java applets进行通讯,Java Applets使用Java的Thread.sleep()方法休眠线程(不占用资源)。
1
2
3
4
5
6
7
8
9
10
|
<applet code=
"DevCheater.class"
name=
"devCheater"
id=
"devCheater"
mayscript=
"true"
height=
"1"
width=
"1"
></applet>
<script type=
"text/javascript"
>
function sleep(milliSeconds){
// runs Java Applets sleep method
document.devCheater.sleep(milliSeconds);
}
</script>
|
此方法不冻结所有页面中的其他javascript(使用Chrome时除外)。不幸的是,它需要安装一个Java插件。
通过Flash实现JavaScript sleep
如果我们尝试了Java,为什么不试试ADOBE FLASH。我创建了一个Flash应用程序,有一个方法叫flashSleep()。我使用javascript调用我的flash方法,并传入需要sleep的毫秒数。但不幸的是,这种方法在大多数的浏览器中也导致了阻塞。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<script type=
"text/javascript"
>
function sleep(milliSeconds){
// call sleep method in flash
getFlashMovie(
"flashSleep"
).flashSleep(milliSeconds);
}
function getFlashMovie(movieName){
// source: http://kb2.adobe.com/cps/156/tn_15683.html
var isIE = navigator.appName.indexOf(
"Microsoft"
) != -1;
return
(isIE) ? window[movieName] : document[movieName];
}
</script>
|
1
2
3
4
5
6
7
8
|
<
object
classid=
"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase=
"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0"
width=
"50"
height=
"50"
id=
"flashSleep"
align=
"middle"
>
<param name=
"allowScriptAccess"
value=
"sameDomain"
/>
<param name=
"allowFullScreen"
value=
"false"
/>
<param name=
"movie"
value=
"flashSleep.swf"
/>
<param name=
"quality"
value=
"high"
/>
<param name=
"bgcolor"
value=
"#ffffff"
/>
<embed src=
"flashSleep.swf"
quality=
"high"
bgcolor=
"#ffffff"
width=
"50"
height=
"50"
name=
"flashSleep"
align=
"middle"
allowScriptAccess=
"sameDomain"
allowFullScreen=
"false"
type=
"application/x-shockwave-flash"
pluginspage=
"http://www.macromedia.com/go/getflashplayer"
/>
</
object
>
|
测试发现,Flash也不是理想的方式。
通过XMLHttp实现JavaScript sleep
另一种方法是使用XMLHttp进行服务器通信。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<script type=
"text/javascript"
>
function sleep(milliSeconds){
var resource;
var response;
if
(typeof ActiveXObject ==
'undefined'
){
resource =
new
XMLHttpRequest();
}
else
{
// IE
resource =
new
ActiveXObject(
"Microsoft.XMLHTTP"
);
}
try
{
resource.open(
'GET'
,
'sleep.php?milliSeconds='
+ milliSeconds,
false
);
resource.send(null);
response = resource.responseText;
// JavaScript waits for response
}
catch
(e){
alert(e);
}
return
true
;
}
</script>
|
1
2
3
4
5
6
7
8
9
10
|
<?PHP
$milliSeconds
=
intval
(
$_REQUEST
[
'milliSeconds'
]);
if
(
$milliSeconds
> 60*1000){
// limit server abuse
$milliSeconds
= 10;
}
usleep(
$milliSeconds
* 1000);
// note: usleep is in micro seconds not milli
echo
"done"
;
?>
|
该方法并不占用用户计算机的CPU资源,但加重了服务器额外的负载。而且该方法阻塞了浏览器中其它javascript,对于服务器来说产生了类似DDos的攻击。
结论
从测试数据来看,许多的实现都有一定的副作用,所以setTimeout()或setInterval()函数还是最好的选择。