作者sk1765 (鼎玉铉)
看板Ajax
标题Re: [讨论] javascript是共时、多执行绪吗?
时间Mon Nov 7 14:06:32 2011
为了确认同一个页面多个iframe也只有一个thread
我刚实测了同一个页面两个iframe 里面各自跑timer
两个iframe同时去更新父视窗
还是用原来的12一组 34一组
测试结果 12 34不会交叉出现 13 24 或14 32都不会出现
tyx的说法是正确的 不管ie,ff,chrome,opera都只有一个thread
所以opera的文件?? 不了解是不是他们自己也写错
程式连结:
http://www.briantest.site88.net/test.html
程式如下:
test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml" lang="zh-TW" xml:lang="zh-TW">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>iframe multithread?</title>
<script>
i = 0;
</script>
</head>
<body>
<div id='show'></div>
<iframe src='test1.html'></iframe>
<iframe src='test2.html'></iframe>
</body>
</html>
--------------------------------------------------------------
test1.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml" lang="zh-TW" xml:lang="zh-TW">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>iframe1</title>
<script>
var s=null,t1=null;
window.onload = function(){
s = parent.document.getElementById('show');
t1 = setInterval( A ,1);
}
function A() {
var x = window.parent.document.createTextNode('1');
s.appendChild(x);
var y = window.parent.document.createTextNode('2');
s.appendChild(y);
window.parent.i++;
if (window.parent.i>=1000) {
clearInterval(t1);
}
if (window.parent.i%10==0)
s.appendChild(window.parent.document.createElement('br'));
}
</script>
</head>
<body>
</body>
</html>
----------------------------------------------------
test2.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"
http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml" lang="zh-TW" xml:lang="zh-TW">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>iframe2</title>
<script>
var s=null,t2=null;
window.onload = function(){
s = parent.document.getElementById('show');
t2 = setInterval( B ,2);
}
function B() {
var x = window.parent.document.createTextNode('3');
s.appendChild(x);
var y = window.parent.document.createTextNode('4');
s.appendChild(y);
window.parent.i++;
if (window.parent.i>=1000) {
clearInterval(t2);
}
if (window.parent.i%10==0)
s.appendChild(window.parent.document.createElement('br'));
}
</script>
</head>
<body>
</body>
</html>
所以我们就当alert是一个特例吧 我在opera ff 都看到两个A叠在一起
不知道这算不算bug
有错请指教
※ 引述《tyx (?????????????????)》之铭言:
: 在同一个 page 里 只有一个 thread 在执行
: 不管有几个 iframe 都一样 (但 Opera 不是 推文有连结)
: 那为何有不同的行为
: 我以 senser 的范例作说明
: 1. FireFox
: 当 FF 执行 $('ifa').src = 'javascript:alert("A");alert("B")'; 时
: 会先 parse 这段 javascript 但并不会立刻执行此 js
: 而是产生一个 '要执行此 js 的 event'(暂时称为 event1) 在 event queue 里
: 之後执行下一行 $('ifb').src = ... 并产生 event2
: 然後 thread 回去 event queue 取到 event1 并执行 alert("A")
: 此时会看到 alert("A") 的 dialog
: 此 dialog 出现时 除了此 dialog 以外 page 的 input 都会被 disabled
: 所以不会有其他 UI events
: 当 alert("A") dialog 执行时 内部也有个 event loop 在取 event 出来执行
: 所以会取到 event2 并执行 alert("C")
: 当你按掉 alert("C") 之後 会立刻执行 alert("D")
: 再按掉 alert("D") 又会回到 alert("A") 的内部 event loop
: 再按掉 alert("A") 之後 会执行 alert("B")
: 所以会看到 alert("A") 出现後 立刻出现 alert("C")
: 然後结束 alert("C") 立刻出现 alert("D")
: 然後结束 alert("D") 回到 alert("A")
: 然後结束 alert("A") 立刻出现 alert("B")
: 2. IE
: 当 IE parse 完 js 之後会立刻执行 所以才会
: 出现 A 按掉A之後出现 B 按掉 B 之後出现 C 按掉 C 之後出现 D
: ps: 至於 console.log("A") 会依序出现
: 是因为执行 console.log("A") 时
: 并不会偷偷跑 event loop
: 所以 C D 不会偷跑罗
: ※ 引述《senser (彷佛曾经一起死过)》之铭言:
: : alert在不同thread下(iframe)到底会怎样我倒是没有研究过
: : 我把您的code改成
: : var $ = function(id){return document.getElementById(id);};
: : $('ifa').src = 'javascript:alert("A");alert("B")';
: : $('ifb').src = 'javascript:alert("C");alert("D")';
: : 我刚刚试的结果
: : 意外发现FF下会先出现A(很快来不急按) 然後被C盖住 之後D 回到A 最後B
: : 这有点两个alert一起出现的味道(只是被盖住了)
: : IE的结果就是同一时间只有一个alert 然後ABCD
: : 这跟browser的实作有关
: : 我只能推断 FF的alert出现时 容许其他的thread的alert也出现
: : (不确定是 出现两个 一个被"盖住" 或是同一个alert box然後内容被取代
: : 在我的FF中没办法用滑鼠移动alert box)
: : 而IE的UI不容许这种情况出现
: : 然後回到问题
: : 在两个thread并行下 ACBD交叉出现我觉得是有可能的
: : (但我不知道哪个browser可以 也没试着去制造出来过)
: : 但是在一个event-driven 的single thread中(前篇文章) 是不会发生的
: : 一个callback只会执行完在去执行下一个 不会互相跳来跳去
: : ==============
: : 各家浏览器对alert的实作略有不同
: : 一般当alert出现时 产生alert那段程式会暂停 直到按了之後在继续
: : 然而有些浏览器在alert出现时 会继续dispatch的动作
: : dispatch进去的handler中 如果是UI trigger的 他不会执行
: : 但如果是non-UI 的event handler 像是ajax的callback
: : 在某些browser中是会同时执行的 即使你的alert还挂在那里
: : 所以用alert debug的习惯是非常不好的
: : 在你还没按下时 可能有东西就跑起来了
: : 以致於你alert出来的变数也有可能被影响 而看到错的值
: : 真的用在application中更是有可能造成错误 (confirm,prompt等等都一样)
: : 根据你甚麽时候按下去 你的那段程式才会继续跑
: : 但是你的non-UI event在背後一样的dispatch然後fire (如page load,timeout)
: : 所以希望大家改掉直接用这种东西当UI的习惯 避免不必要的timing issue
: : 全部的UI都要自己兜出来比较好
: : ===
: : 这里就有现成的例子
: : 刚刚用FF看 好像是CDAB (按掉CD时A或若隐若现)
: : 如果你没有注意那个若隐若现的A 你就会以为他的顺序真的是CDAB这样
: : 然而如果你改成console.log("A")
: : 就会知道他的真正的顺序是ABCD
: : 给大家参考:D
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 175.182.110.93
※ 编辑: sk1765 来自: 175.182.110.93 (11/07 14:14)
1F:→ weiyucsie:opera的alert可以移开阿XD 11/07 14:19
2F:→ sk1765:我知道阿 但如果只有一个thread 应该是同时只会一个阿 11/07 14:23
3F:→ weiyucsie:老实说,用alert原因是因为可以做到暂停的效果~ 11/07 14:30
4F:→ weiyucsie:比较好控制 11/07 14:32
6F:→ weiyucsie:这时候console.log会在alert之後执行 11/07 14:33
7F:→ weiyucsie:当我把alert的位置放在不同的位置上 11/07 14:34
8F:→ weiyucsie:选任意一个alert按下去,出现对应的console.log 11/07 14:34
9F:→ weiyucsie:只是你说的12和34的情形,测试起来也好像是这样 11/07 15:14
10F:→ weiyucsie:可能还要确认看看吧 >.< 11/07 15:14
11F:推 tyx:ie ff chrome 在 alert 时 不会跑 event loop 11/07 16:22
12F:→ tyx:所以不会 event 重入 11/07 16:23
13F:→ tyx:勿打 是 ie 与 chrome 11/07 16:24
14F:→ tyx:ie 与 chrome 多个 iframe 也是同一个 thread 11/07 16:24
15F:→ tyx:一个 iframe 先 setTimeout 之後另一个跑无穷回圈 11/07 16:26
16F:→ tyx:此时 timeout 不会执行 若是不同 thread 应该要有 11/07 16:27
17F:→ tyx:timeout 的event 11/07 16:28
18F:→ tyx:也可写个 plugin 来验证 看看不同 iframe 11/07 16:29
19F:→ tyx:是不是有相同 thread id 11/07 16:29
20F:→ weiyucsie:刚刚用process explorer查看 chrome果然只有一个XD 11/07 16:38
21F:→ weiyucsie:不过opera也只有一个>.< 11/07 16:40
22F:→ weiyucsie:只是又与我刚刚的实验结果感觉不太一样~ 11/07 16:41
23F:推 herb123456:楼上 multi-thread和multi-process不一样... 11/20 14:48
24F:→ weiyucsie:process explorer有个Thread tab阿 有列出tid... 11/22 22:52