论坛首页 Web前端技术论坛

如何在JavaScript中实现某个方法执行超时后则继续执行其它方法?

浏览 18806 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-11-12  
fins 写道
hax 写道
myy 写道
可以考虑用 window.open() 开新窗口实现,这个在IE下肯定是多线程的


You r wrong. They always in one script thread.



这个我没明白
为什么新开个窗口后, 新窗口内执行的 js 和 原窗口是一个线程????

比如 原窗口内循环执行一个函数.
中途开了一个新窗口 新窗口内也是调用一个函数
难道那个窗口的函数要执行完了
原窗口的才会继续执行下去????

如果open的窗口 和原窗口是一个 script thread
那么 通过 <a href=... target='_blank' >....
打开的呢?? 也是???


你可以尝试一下你所构思的测试例子,看看结果如何。
0 请登录后投票
   发表时间:2007-11-12  
fins 写道
to Hax
下面一段代码,确实是先执行的B, 而不是A执行完之后再执行的B啊


当然是先B后A,因为根据timer的设定,B在A前。

我说的意思恰恰是,B总在A前,即使B是一个heavytask超过了A的timer所设定的时间,但是由于script引擎是单线程的,A总是要等到B执行完毕后才有机会执行。
0 请登录后投票
   发表时间:2007-11-12  
这些我理解了
但是 这个还是没明白

引用

这个我没明白
为什么新开个窗口后, 新窗口内执行的 js 和 原窗口是一个线程????

比如 原窗口内循环执行一个函数.
中途开了一个新窗口 新窗口内也是调用一个函数
难道那个窗口的函数要执行完了
原窗口的才会继续执行下去????

如果open的窗口 和原窗口是一个 script thread
那么 通过 <a href=... target='_blank' >....
打开的呢?? 也是???

0 请登录后投票
   发表时间:2007-11-12  
fins 写道
to hax
我明白你的意思了
其实你是指, 理论上我说的对
但是实际情况中 我例子中的A方法会一直占有CPU ,使得方法B根本得不到运行的机会,对吧?


我的意思是,由于JS是单线程执行的(除了某些带有扩展特性的引擎,如rhino),所以脚本其实没有可能进行真正意义上的多线程。

注意setTimeout/setInterval并非JS规范的一部分,而是浏览器提供的特性。而且它们本质上只是一个排程器,不可能中断尚未执行完成的脚本或者重入任何一个方法。否则必然会出现语义上的问题。真正多线程,必定要带有其它的原语,如锁定、同步、信号量——JS本身一样都没有。

我们可以用setTimeout来实现Executor和Queue,但是进入一个queue的任何一个任务一旦执行,就不可能被中断,只有它执行完成了,其他task才有机会执行。所以你必须手动把heavy的task分解成一系列小的task,才能模拟多线程。

未来的JS 2.0,我们仍然不会有多线程(除了引擎自己的扩展),但是我们有了yield,能以协程方式进行并行编程!
0 请登录后投票
   发表时间:2007-11-12  
fins 写道
这些我理解了
但是 这个还是没明白


是否是新开窗口,对于JS来说没有意义。

除非是两个完全没有任何关联的浏览器会话,理论上是可以在两个独立线程中的。

顺带说一下,JS本身一定是单线程的(除了特定的引擎扩展之外),这并不妨碍浏览器的其它部分是多线程的(问题是现有的浏览器实现,往往把脚本执行放在浏览器的主线程中)。但是其它任何一种异步机制或者外部多线程,如果牵涉到脚本,最终都会归并到JS的这一个线程中。所以XHR是异步的,CSS渲染是异步的,打开一个新窗口是异步的……都不能改变JS脚本的执行顺序。
0 请登录后投票
   发表时间:2007-11-12  
非常感谢
以前对这方面的了解确实太少了 现在知道了

谢谢


0 请登录后投票
   发表时间:2007-11-12  
hax 写道
fins 写道
这些我理解了
但是 这个还是没明白


是否是新开窗口,对于JS来说没有意义。

除非是两个完全没有任何关联的浏览器会话,理论上是可以在两个独立线程中的。

顺带说一下,JS本身一定是单线程的(除了特定的引擎扩展之外),这并不妨碍浏览器的其它部分是多线程的(问题是现有的浏览器实现,往往把脚本执行放在浏览器的主线程中)。但是其它任何一种异步机制或者外部多线程,如果牵涉到脚本,最终都会归并到JS的这一个线程中。所以XHR是异步的,CSS渲染是异步的,打开一个新窗口是异步的……都不能改变JS脚本的执行顺序。


据我所知,IE6 (IE7标签页方式不清楚) 用 open(), _balnk, Ctrl+N 等各种方式打开的新窗口都是在独立的线程中运行的,并且同时都属于一个IE进程,“浏览器的主线程”这种说法也不确切,事实上,同一个IE进程每个IE窗口线程都是平等的,根本没有哪个是“主线程”之说。也就是说,每个IE窗口线程中都有“全套”的东西,包括 js引擎。(不过,底层的网络通讯采用了线程池,这个是共享的)。

这样,虽然“JS本身一定是单线程的”,但是open()创建了两套“在不同线程中的js引擎环境”,通过这样来模拟 LZ 的要求是可行的。
0 请登录后投票
   发表时间:2007-11-12  
晕 本来以为 hax把我教明白了 这一下又糊涂了

有没有官方的说法啊????

afcn0  hax jindw ....  等等各位js研究的大牛们
快出来给个正确答案啊
0 请登录后投票
   发表时间:2007-11-12  
没有过多分析,只是思维上的猜测,window.open必须等待打开页面onload彻底执行完才返回,所以和原页面是单线程(此点有待实验证实),但是即便如此setTimeout可以注册在load事件后执行,所以应该可以实现多窗口多js并行
timeout interval应该看js解释器是如何实现的,比如ie就永远是单线程,alert都会终止timer的计时,但是其他解释器则不然,所以至少ie上面是没有多线程一说的,也许ff或其他确实可以实现多timer并行执行(没测试),但是还是那句话,ie不支持也是有其道理的,不要把web弄的太复杂了
...我一个菜鸟被楼上大哥称为大牛,烧的难受
0 请登录后投票
   发表时间:2007-11-12  
补充个测试
<div id="test">
</div>
<script>
function aaa(){
var temp=new Date().getTime();
for (var i=0;i<10000 ;i++ )
{
	if(window.t)
	{
	document.getElementById("test").innerHTML="thread2 run";
	}
	i=i+10000;
	i=i-10000;
}
document.getElementById("test").innerHTML+=new Date().getTime()-temp;
return i;
}
function bbb(){
t=1234;
}
setTimeout(aaa,5);
setTimeout(bbb,10);

</script>

opera ie ff上面都没有显示thread2 run所以基本肯定js就是单线程的
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics