作者senser (彷佛曾经一起死过)
看板Ajax
标题Re: [讨论] javascript是共时、多执行绪吗?
时间Mon Nov 7 19:06:07 2011
就我所知 目前的borwser对於每一段script
都是先parse (js特殊的hoist现象就是这里发生的)
之後执行top-level应该执行的东西(load完後马上要执行的)
接着开始listen event
每一段script block都是一起parse
然後执行
接着继续下面的HTML Parse (script blocking就是这样产生的 所以要放下面)
在这个parse过程 他会调整你的code
像是一个context里的变数会帮你拿到最上面帮你宣告好之类的(hoist)
在之前的例子里 一个iframe只有一行code 我想有99.99%的机率是ABCD
不管哪个browser应该都是这样
第一个iframe parse完就开始 run了
第二个iframe说甚麽也不会比较快 (CDAB)
然後只有两个log间也是不太可能被插队 (ACDB)(ACDB)..etc
alert(confirm prompt等等)的例子为甚麽混淆视听
是因为这和browser本身UI的实作有关 而和他对Javascript的实作关联不大
(像是跑出来时 不接受你按按键 这是browser的UI问题 而不是js问题)
在我的FF中 有看到alert A一闪 然後被C盖住
我想他就是会让後来出现的alert盖住前面
CD按完就可以看到下面的A了 A按了当然就跑出接下来的B
而IE的例子中
好像不可以同时有两个alert
我甚至不知道他有没有multi-thread
因为第一个alert A出现之後
如果有multi-thread 紧接着alert C应该也蠢蠢欲动才是
但也有可能 他的alert出现时 整个HTML parse thread也停下来了
实验是在你alert後面放html 按下去前看不到
(但rende和parse又是不一样的东西 时间也不会一样 所以这无法证明)
所以A按完後 为甚麽是B而不是C 这我目前就不知道了
只能说和他的alert实作有关
所以用alert去看这种thread的问题 我觉得是会有很多误导的
※ 引述《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: 71.107.60.113
1F:→ tyx:假设是 multithread 一定有机会出现 ACBD or ACDB 11/07 19:36
2F:→ tyx:不管 alert 是否 suspend 其他动作 11/07 19:37
3F:→ tyx:不用同时出现 alert 就可证明是多绪 11/07 19:38
4F:→ weiyucsie:context-switch的间隔有没有差别?XD 11/07 19:43