Re: [討論] javascript是共時、多執行緒嗎?
看來大家對這個問題都相當有興趣
我試著虐待一下我的FF 看看能不能證明有沒有multi-thread
(說真的opera說有 我也不確定 說不定他在騙我們XD)
為了測試
首先 你要在你的url打 about:config
搜尋 extensions.firebug.console.logLimit
然後把他調成十萬之類的
接著開一個空白文件叫做"thread.html"
然後貼上:
<html>
<head></head>
<body>
<iframe style="width:200px;height:200px" src='thread.html?id=1' ></iframe>
<iframe style="width:200px;height:200px" src='thread.html?id=2'></iframe>
<iframe style="width:200px;height:200px" src='thread.html?id=3'></iframe>
<iframe style="width:200px;height:200px" src='thread.html?id=4'></iframe>
<iframe style="width:200px;height:200px" src='thread.html?id=5'></iframe>
<script type="text/javascript"
src="" rel="nofollow">http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script>
var MultiThread = {
start : function(){
if(location.href.indexOf("?") == -1) return;
this.stopRecursion();
this.id = this.getID();
this.doManyLog();
//this.doLogForever();
},
doLogForever : function() {
while(1)
console.log(this.id);
},
doManyLog : function(){
for(var i = 0,count = 3000 ; i < count ; i++){
console.log(this.id);
};
},
getID : function(){
return location.href.split('=')[1];
},
stopRecursion: function() {
$('iframe').each(function(){
$(this).attr('src','');
});
}
};
$(function() {
MultiThread.start();
})
</script>
</body>
=============================
這段code基本上就是利用網址的變化去知道是哪個iframe
如果有multi-thread 迴圈會被中斷 被其他的iframe插隊
在數字不夠多的情況下 你會看到12345一段一段按順序跑完
但是加多一點像是3000時 你就會發現 每一個迴圈會被插隊
然後交互著跑 我想這應該是multi-thread的特性
另一個怪招是
如果你真的怒了 給他加到十萬或是無限迴圈之類的
你會發現你的FF投降時 會問你這一段script太久了 要不要中斷
然後這個視窗不只一個 每個iframe裡的script都會問你
我想這意味著 每個iframe都執行script了
而在第一個沒跑完的情況下 其他也執行到了 代表有插隊情況
所以這可能也代表著不只一個 thread
所以我想 大概是有multi-thread
※ 引述《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
: ※ 引述《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/
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 71.107.60.113
※ 編輯: senser 來自: 71.107.60.113 (11/07 18:20)
→
11/07 18:49, , 1F
11/07 18:49, 1F
→
11/07 18:50, , 2F
11/07 18:50, 2F
→
11/07 19:06, , 3F
11/07 19:06, 3F
→
11/07 19:07, , 4F
11/07 19:07, 4F
→
11/07 19:07, , 5F
11/07 19:07, 5F
→
11/07 19:07, , 6F
11/07 19:07, 6F
→
11/07 19:10, , 7F
11/07 19:10, 7F
→
11/07 19:10, , 8F
11/07 19:10, 8F
→
11/07 19:28, , 9F
11/07 19:28, 9F
→
11/07 19:29, , 10F
11/07 19:29, 10F
→
11/07 19:29, , 11F
11/07 19:29, 11F
推
11/07 19:30, , 12F
11/07 19:30, 12F
→
11/07 19:31, , 13F
11/07 19:31, 13F
→
11/07 19:33, , 14F
11/07 19:33, 14F
→
11/07 19:35, , 15F
11/07 19:35, 15F
→
11/07 19:41, , 16F
11/07 19:41, 16F
→
11/07 19:41, , 17F
11/07 19:41, 17F
→
11/07 19:42, , 18F
11/07 19:42, 18F
→
11/07 19:46, , 19F
11/07 19:46, 19F
→
11/07 19:48, , 20F
11/07 19:48, 20F
→
11/07 19:49, , 21F
11/07 19:49, 21F
→
11/07 19:53, , 22F
11/07 19:53, 22F
→
11/07 19:53, , 23F
11/07 19:53, 23F
→
11/07 19:54, , 24F
11/07 19:54, 24F
→
11/07 19:59, , 25F
11/07 19:59, 25F
→
11/07 20:00, , 26F
11/07 20:00, 26F
→
11/07 20:00, , 27F
11/07 20:00, 27F
→
11/07 20:01, , 28F
11/07 20:01, 28F
→
11/07 20:15, , 29F
11/07 20:15, 29F
→
11/07 20:16, , 30F
11/07 20:16, 30F
→
11/07 20:48, , 31F
11/07 20:48, 31F
→
11/07 20:48, , 32F
11/07 20:48, 32F
→
11/07 20:48, , 33F
11/07 20:48, 33F
→
11/07 20:48, , 34F
11/07 20:48, 34F
→
11/07 20:48, , 35F
11/07 20:48, 35F
→
11/07 20:48, , 36F
11/07 20:48, 36F
→
11/07 20:49, , 37F
11/07 20:49, 37F
→
11/07 20:49, , 38F
11/07 20:49, 38F
→
11/07 20:50, , 39F
11/07 20:50, 39F
→
11/07 20:50, , 40F
11/07 20:50, 40F
→
11/07 20:51, , 41F
11/07 20:51, 41F
→
11/07 21:43, , 42F
11/07 21:43, 42F
→
11/07 21:43, , 43F
11/07 21:43, 43F
→
11/08 14:19, , 44F
11/08 14:19, 44F
→
11/08 14:21, , 45F
11/08 14:21, 45F
→
11/08 23:49, , 46F
11/08 23:49, 46F
→
11/08 23:50, , 47F
11/08 23:50, 47F
→
11/08 23:51, , 48F
11/08 23:51, 48F
→
11/08 23:52, , 49F
11/08 23:52, 49F
→
11/08 23:53, , 50F
11/08 23:53, 50F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 9 之 11 篇):
Ajax 近期熱門文章
PTT數位生活區 即時熱門文章