Re: [討論] javascript是共時、多執行緒嗎?
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
※ 引述《senser (彷彿曾經一起死過)》之銘言:
: 跟大家分享一下 我對一般常見的browser處理javascript的認知
: 有錯誤請大家不吝指教
: 先回答標題好了
: 就我所知 目前javascript在browser的implementeation中
: 在一個"window"下中只有一個thread 在這種情況下 你可以說javascript是單一thread
: 事實上大部分的時候 我們只要以這出發點來考慮問題就足夠了
: 然而 如果你的頁面中有iframe 他會有另外一個window去維護另一個thread
: 在同網域下 他甚至可以存取相同的global物件 造成所謂的race condition
: 在這種狀況下 你可以說javascript 是 multi-thread 我想也是合理的
: =======================
: 所以說 與其討論javascript到底是不是multi-thread
: 其實應該討論的問題是 browser的實作方式
: 首先我們開啟一個頁面 在這個window中會開啟一個thread 處理包括
: 1.html的parse
: 2.dispatching of events
: 3.執行javascript
: 然後在parse的過程中 如果遇到某些tag像是img, embed, iframe,object 等等
: 他會開啟另外一個thread去下載,render,或是執行iframe裡面的js等等
: 這也是為甚麼 我們會看到在load一個網頁 下載圖片是分開的 每張獨立下載 獨立顯示
: 同時這種作法 也大大加速了我們顯示整個網頁的速度
: 而這和我們的問題有甚麼關係呢?
: 在我們前端開發人員的聖經"High Performance Web Sites"中提到
: 我們應該盡量的把javascript放在網頁的下面
: 為甚麼呢 因為在同一個window的single thread中 如果遇到<script>
: html parsing的動作會停下來 直到
: 1.下載 javascript(如果是外部連結的話)
: 2.parse
: 3.執行
: 三個動作結束後 才會繼續往下
: 如果這個javascript特別久 那下面網頁就久久不parse,整個page loading就卡在那裏
: 所以呢 你應該已經猜到 在你load page時 不同<script>間的javascript執行一定是分開
: 的
: 只有一段<script>跑完 才有機會繼續往下parse HTML
: 也才有機會遇到另外一個<script> 然後執行它
: 而這個部分 我相信每個人都可以直觀的觀察到 這是single thread的感覺
: 那為甚麼有人會提出這類的問題
: 我想主要是因為javascript的一些feature如ajax,timer,alert...等等造成困惑
: 要理解這些困惑 我們要先理解 javascript是怎麼被執行的
: 以下有兩種狀況會執行js
: 1.page load時立刻執行的js
: 2.event handler
: 第一種我們已經討論過了 很單純的由上往下 一個一個來
: 第二腫 在js中我們都視為一種callback 當事件引發時 才會執行
: 在browser對js的處理中 它maintain一個queue叫做 "Dispatch Sequence"
: 當事件觸發時 會立刻把handler放到裡面(這動作叫作dispatch)
: 然後根據先來後到的順序執行handler
: 而在這過程中 當前一個handler沒跑完之前 下一個hander不會被執行
: 所以說 js依然是single thread
: timeout,或是ajax callback等等 我們都要視為是一個event 一樣是用這個規則在跑
: 所以 timeout 5秒不一定會在5秒時跑 ajax callback也不一定會在respose 抵達時馬上
: fire
: 一切都要看 前面的handler執行完了沒 輪到他了沒
: (題外話 alert 是個special case, 每個browser不太一樣 , 寫js的人要盡量少用)
: 那最後回到我們的問題來
: 那個alert ABCD會不會交叉出現呢 答案是不會 (alert要少用 像是sk1765的test case就
: 非常好)
: 相信你已經知道 在timeout中的function A B都是一個event handler(callback)
: 在執行時 會結束才有可能去執行另一個 所以不會ABCD交叉出現
: 最後我想說的是 js要看成是 event-driven的東西
: 用thread去分析 就會陷入把他拆成一行一行看的陷阱
: 而event-driven 產生的timing issue 對我來說 也是js bug中最難trace的一種
: 文章寫的有點長 但其實還有很多細節
: opera這篇文章寫得非常非常好 有興趣的各位可以參考看看
: http://dev.opera.com/articles/view/timing-and-synchronization-in-javascript/
: ※ 引述《TonyQ (自立而後立人。)》之銘言:
: : javascript 是同步的
: : 也就是不會有兩行 statement 同時執行的
: : 但是他可以是多執行續。
: : 也就是假設你有一個 funciont 是
: : function A(){
: : alert("A");
: : alert("B");
: : }
: : function B(){
: : alert("C");
: : alert("D");
: : }
: : 透過 setTimeout / setItnerval ,
: : 是有可能會發生這樣的執行序
: : alert("A");//from A
: : alert("C");//from B
: : alert("B");//from A
: : alert("D");//from B
: : 你把 js 底層的引擎想像成一個 queue ,
: : 有要執行的指令就推進去,引擎會去跑他,
: : 但同時間他只能處理一個指令。
: : 一般當你真的很需要控制執行的順序的時候,
: : 我們會多加幾個 flag 作為 lock ,或者自己實做queue。
: : 但是基本上 javascript 要作到 java 的 synchronized keyword 做的事情,
: : 是沒有辦法保證一定做的到的,最好盡量避免這麼嚴苛的狀況。:P
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 71.107.60.113
討論串 (同標題文章)
Ajax 近期熱門文章
PTT數位生活區 即時熱門文章