随笔-121  评论-1534  文章-1  trackbacks-99

一道JavaScript面试题(setTimeout)

下面的代码,多久之后会弹出'end'? 为什么?

var t = true;

setTimeout(function(){ t = false; }, 1000);

while(t){ }

alert('end');

这是以前在想有没办法实现阻塞javascript线程的时候(即实现sleep方法),想过的一种实现。

很简单,是吧?

是吗?

作者:QLeelulu Follow QLeelulu on Twitter
出处:http://QLeelulu.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利
标签: javascript
posted on 2011-06-13 18:13 Q.Lee.lulu 阅读(4467) 评论(37) 编辑 收藏

评论:
#1楼 2011-06-13 18:28 | Evanlee      
马上
 回复 引用 查看   
#2楼 2011-06-13 18:31 | Gray Zhang      
无解吧……?
 回复 引用 查看   
#3楼 2011-06-13 18:43 | 大罗卜      
根据设定的时间执行,但是执行的时候while循环语句已经开始执行了,由此判断出,该程序会导致页面的死循环,页面无响应
 回复 引用 查看   
#4楼 2011-06-13 18:47 | Franky      
自然无解. timeout 回调 是要等退出全部 execution context stack 后,才去计时的.
 回复 引用 查看   
#5楼 2011-06-13 18:48 | 木鱼      
@Evanlee
典型的死循环……js是单线程执行的,while里面死掉的时候setTimeout里面的函数是没机会执行的。

 回复 引用 查看   
#6楼 2011-06-13 19:06 | 马甲门      
setTimeout 只是挂了个定时任务,但是 JS 本身是单线程的,while 那里肯定死掉了。
 回复 引用 查看   
#7楼 2011-06-13 20:16 | shuxiang      
事实证明,浏览器会谈框停止脚本或浏览器崩掉,6楼正解。话说你现在很牛B了啊!
 回复 引用 查看   
#8楼 2011-06-13 20:20 | 坎普利特      
学习了 = =
 回复 引用 查看   
#9楼[楼主] 2011-06-13 20:35 | Q.Lee.lulu      
引用Franky:自然无解. timeout 回调 是要等退出全部 execution context stack 后,才去计时的.

确定是退出全部 execution context stack 后,才去计时的?

 回复 引用 查看   
#10楼[楼主] 2011-06-13 20:37 | Q.Lee.lulu      
引用木鱼:
@Evanlee
典型的死循环……js是单线程执行的,while里面死掉的时候setTimeout里面的函数是没机会执行的。

^_^!
死掉这个词用的不怎么恰当,呵呵

 回复 引用 查看   
#11楼[楼主] 2011-06-13 20:37 | Q.Lee.lulu      
@shuxiang
香香你居然跑来博客园混了 ?

 回复 引用 查看   
#12楼 2011-06-13 21:05 | 563812344[未注册用户]
死循环了,如果没有死循环也不会马上弹出来。。。要1s后,准不准就不一定了,js是单线程,而且类似定时器这样的玩意儿都不准。以前用c++写程序,本机测试少于50毫秒就不准了。
 回复 引用   
#13楼 2011-06-13 21:05 | Franky      
引用Q.Lee.lulu:
引用Franky:自然无解. timeout 回调 是要等退出全部 execution context stack 后,才去计时的.

确定是退出全部 execution context stack 后,才去计时的?


有问什么问题?

 回复 引用 查看   
#14楼 2011-06-13 21:07 | 行云_流水      
@Franky
如果想要使用多线程。怎么办呢?

 回复 引用 查看   
#15楼 2011-06-13 21:17 | MK2      
lulu这是想害大家卡死浏览器吧。。。哈哈
 回复 引用 查看   
#16楼[楼主] 2011-06-13 21:21 | Q.Lee.lulu      
引用Franky:
引用Q.Lee.lulu:
引用Franky:自然无解. timeout 回调 是要等退出全部 execution context stack 后,才去计时的.

确定是退出全部 execution context stack 后,才去计时的?


有问什么问题?

先计时开始,然后再去while true的哦

 回复 引用 查看   
#17楼 2011-06-13 21:30 | Franky      
很不幸
引用Q.Lee.lulu:
引用Franky:
引用Q.Lee.lulu:
引用Franky:自然无解. timeout 回调 是要等退出全部 execution context stack 后,才去计时的.

确定是退出全部 execution context stack 后,才去计时的?


有问什么问题?

先计时开始,然后再去while true的哦


很不幸,并不是这样..

 回复 引用 查看   
#18楼[楼主] 2011-06-13 21:40 | Q.Lee.lulu      
@Franky
很不幸,计时确实已经开始了
1000毫秒后确实计时也结束了
那,然后呢?
嗯,问题就在这里了~~

 回复 引用 查看   
#19楼 2011-06-13 21:55 | Franky      
引用Q.Lee.lulu:
@Franky
很不幸,计时确实已经开始了
1000毫秒后确实计时也结束了
那,然后呢?
嗯,问题就在这里了~~


饿.我表达有问题..计时是timeout api被调用时. 但这个callback 会在execution context stack 全部退出后.

 回复 引用 查看   
#20楼 2011-06-13 21:58 | 打酱油的。。。[未注册用户]
setTimeout(function () { alert("start");}, 10);
alert('end');

先弹出end,再弹出start。

 回复 引用   
#21楼 2011-06-13 22:03 | Franky      
<script>

setTimeout(function () {alert(1);});

</script>

<script>
var t = new Date;
while(new Date - t < 1000);
</script>

<script>
alert(2);
</script>

事实要考虑的东西,比想象的要多. 譬如 HTML Parser 的预读. 这段代码在非opera下就比较有趣.

 回复 引用 查看   
#22楼 2011-06-13 22:34 | wangtz      
引用马甲门:setTimeout 只是挂了个定时任务,但是 JS 本身是单线程的,while 那里肯定死掉了。

果然是这样!学习了!

 回复 引用 查看   
#23楼 2011-06-13 23:07 | Jeff Wong      
老大,你的这篇直接导致了我的再思考 重新认识javascript的settimeout和异步
 回复 引用 查看   
#24楼[楼主] 2011-06-13 23:32 | Q.Lee.lulu      
引用Franky:
<script>

setTimeout(function () {alert(1);});

</script>

<script>
var t = new Date;
while(new Date - t < 1000);
</script>

<script>
alert(2);
</script>

事实要考虑的东西,比想象的要多. 譬如 HTML Parser 的预读. 这段代码在非opera下就比较有趣.

有意思,opera下何解?

 回复 引用 查看   
#25楼 2011-06-14 00:30 | Franky      
可以参考:http://www.cnblogs.com/_franky/archive/2010/12/31/1923376.html

个人的一些理解.后面一部分,有提到这个问题.

 回复 引用 查看   
#26楼 2011-06-14 09:00 | 刘江北      
很典型的东西啊,好玩意~~~
 回复 引用 查看   
#27楼 2011-06-14 10:26 | testzhangsan      
要异步?试试老赵的 Jscex
 回复 引用 查看   
#28楼 2011-06-14 15:02 | 幸运猴子      
这个...不能用吧,线程会被阻塞...
 回复 引用 查看   
#29楼 2011-06-14 16:23 | 云霆      
果然是无解,会在while语句这里形成死循环!
 回复 引用 查看   
#30楼 2011-06-14 16:30 | 知乎者也      
页面一直都在加载,不会弹出'end'
 回复 引用 查看   
#31楼 2011-06-14 16:49 | jifsu      
没看评论,我觉得这个在各种浏览器下表现应该不一样.

 回复 引用 查看   
#32楼 2011-06-14 17:02 | jifsu      
时间证明:
狗日的浏览器确实不争气,全部假死
IE6直接崩溃
IE9 提示脚本执行时间过长,是否终止,点击否,IE9崩溃
Firefox4 提示,选否 ,崩溃
opera11 不提示,也不崩溃,无限等待中
safri5 提示,选否,继续提示.....无限循环

 回复 引用 查看   
#33楼 2011-06-14 17:23 | icbj.cn      
假死

 回复 引用 查看   
#34楼 2011-06-15 15:26 | 追杀      
@icbj.cn
opera11 不提示,也不崩溃,无限等待中
-------------------------------------
经测试,耐心等待后会提示脚本繁忙之类的...

 回复 引用 查看   
#35楼 2011-06-15 18:45 | 云和山的彼岸      
试了一下,浏览器死了,哈哈
 回复 引用 查看   
#36楼 2011-06-17 17:46 | shuxiang      
@Q.Lee.lulu
跟煜哥混,是很有前途的,果断来混~~

 回复 引用 查看   
#37楼 2011-08-25 00:27 | yingzai621[未注册用户]
@Q.Lee.lulu
代码改成这样是不是就成功弹出‘end’了?
function a(){}

var t = true;

setTimeout(function(){ t = false; }, 1000);

while(t){a(); }

alert('end');

 回复 引用   
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 2079965 Xk881NTQ1tI=
昵称: lulu
网名: QLeelulu
大学: GDUT
城市: 广州=>珠海
职业: 打字员
CO. : PowerEasy => KingSoft
Mail: QLeelulu@163(gmail).com

Who Am I ?


Follow QLeelulu on Twitter
交流群 ASP.NET MVC交流群:
QQ群:1215279(满)
2群:1214648(满)
3群:47788243
(加的时候请注明)



昵称:Q.Lee.lulu
园龄:4年4个月
荣誉:推荐博客
粉丝:322
关注:7
<2011年6月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

搜索

 

常用链接

我的标签

随笔分类

随笔档案

.NET 资源

PowerEasy

我的好友

积分与排名

  • 积分 - 734675
  • 排名 - 65

最新评论

阅读排行榜

评论排行榜

推荐排行榜