精华帖 (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' >.... 打开的呢?? 也是??? 你可以尝试一下你所构思的测试例子,看看结果如何。 |
|
返回顶楼 | |
发表时间:2007-11-12
fins 写道 to Hax
下面一段代码,确实是先执行的B, 而不是A执行完之后再执行的B啊 当然是先B后A,因为根据timer的设定,B在A前。 我说的意思恰恰是,B总在A前,即使B是一个heavytask超过了A的timer所设定的时间,但是由于script引擎是单线程的,A总是要等到B执行完毕后才有机会执行。 |
|
返回顶楼 | |
发表时间:2007-11-12
这些我理解了
但是 这个还是没明白 ![]() 引用 这个我没明白 为什么新开个窗口后, 新窗口内执行的 js 和 原窗口是一个线程???? 比如 原窗口内循环执行一个函数. 中途开了一个新窗口 新窗口内也是调用一个函数 难道那个窗口的函数要执行完了 原窗口的才会继续执行下去???? 如果open的窗口 和原窗口是一个 script thread 那么 通过 <a href=... target='_blank' >.... 打开的呢?? 也是??? |
|
返回顶楼 | |
发表时间: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,能以协程方式进行并行编程! |
|
返回顶楼 | |
发表时间:2007-11-12
fins 写道 这些我理解了
但是 这个还是没明白 ![]() 是否是新开窗口,对于JS来说没有意义。 除非是两个完全没有任何关联的浏览器会话,理论上是可以在两个独立线程中的。 顺带说一下,JS本身一定是单线程的(除了特定的引擎扩展之外),这并不妨碍浏览器的其它部分是多线程的(问题是现有的浏览器实现,往往把脚本执行放在浏览器的主线程中)。但是其它任何一种异步机制或者外部多线程,如果牵涉到脚本,最终都会归并到JS的这一个线程中。所以XHR是异步的,CSS渲染是异步的,打开一个新窗口是异步的……都不能改变JS脚本的执行顺序。 |
|
返回顶楼 | |
发表时间:2007-11-12
非常感谢
![]() 以前对这方面的了解确实太少了 现在知道了 谢谢 ![]() |
|
返回顶楼 | |
发表时间: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 的要求是可行的。 |
|
返回顶楼 | |
发表时间:2007-11-12
晕 本来以为 hax把我教明白了 这一下又糊涂了
有没有官方的说法啊???? afcn0 hax jindw .... 等等各位js研究的大牛们 快出来给个正确答案啊 |
|
返回顶楼 | |
发表时间:2007-11-12
没有过多分析,只是思维上的猜测,window.open必须等待打开页面onload彻底执行完才返回,所以和原页面是单线程(此点有待实验证实),但是即便如此setTimeout可以注册在load事件后执行,所以应该可以实现多窗口多js并行
timeout interval应该看js解释器是如何实现的,比如ie就永远是单线程,alert都会终止timer的计时,但是其他解释器则不然,所以至少ie上面是没有多线程一说的,也许ff或其他确实可以实现多timer并行执行(没测试),但是还是那句话,ie不支持也是有其道理的,不要把web弄的太复杂了 ...我一个菜鸟被楼上大哥称为大牛,烧的难受 |
|
返回顶楼 | |
发表时间: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就是单线程的 |
|
返回顶楼 | |