2013-04-18 22 views
0

這實在是一個更抽象的問題。我如何確定我不會錯過WebSocket的公開活動?據我瞭解,一旦我調用構造函數,瀏覽器就開始建立連接,所以如果事情變得糟糕,在連接這些事件的處理程序之前可能會觸發打開(或錯誤)事件。我如何確定我不會錯過WebSockets上的「open」事件?

var socket = new WebSocket("ws://www.example.com"); 
/*Because I'm an unlucky guy, the open-event fires before the next line*/ 
socket.addEventListener("open", function(event){...}); 

在這種情況下,我的open-Handler永遠不會被調用。這很可能永遠不會是一個真正的問題,因爲建立連接比執行下一行JavaScript需要更長的時間。然而,同樣可以說對XMLHttpRequest的,有事情的推薦順序是:

var ajax = new XMLHttpRequest(); 
ajax.addEventListener("load", function(event){...}); 
ajax.open(); 
ajax.send(); 

這將確保該事件不會丟失。爲什麼WebSocket在這方面有所不同?我是否忽略了某些事物並忽略了事件並不是一個真正的問題?

謝謝你對此的一些澄清。

回答

2

你對Ajax的第二個例子有一個錯誤的假設。使用Ajax時,只要將兩個事件都包含在同一個同步操作集中,則在調用send之後放置事件處理程序就沒有實際的問題。 Here's a fiddle發送Ajax請求,燒幾秒鐘(足夠的時間來完成提取),然後然後附加偵聽器。正如你所看到的那樣,事件發生得很好。

所以,這是好的:

var ajax = new XMLHttpRequest(); 
ajax.open(); 
ajax.send(); 
ajax.addEventListener("load", function(event){...}); 

由於瀏覽器的JavaScript的單線程性質,load事件實際上並不火,直到當前的代碼運行完畢。 (注:也許這種行爲是在舊的瀏覽器不同,但肯定它是如何工作的支持WebSockets的任何瀏覽器。)

,但是,好:

var ajax = new XMLHttpRequest(); 
ajax.open(); 
ajax.send(); 
setTimeout(function() { 
    ajax.addEventListener("load", function(event){...}); 
}, 1000); 

這是因爲您在兩個異步操作之間創建了爭用條件:setTimeout解析和load事件解僱。只要您在觸發Ajax請求和設置偵聽器之間的延遲處於相同的同步執行中,就沒有「遺漏」Ajax事件的風險。

它與WebSockets的工作方式相同 - 只要構建WebSocket並將偵聽程序附加到同一組同步指令中,就不會錯過open事件。 Here's another fiddle,它執行一個類似的同步等待WebSocket。正如你所看到的,即使在等待幾秒鐘來附加事件監聽器之後,它仍然會觸發。

我不確定在「行爲之前附加聽衆」的做法來自何處。也許它在舊版瀏覽器中很重要,或者對於Ajax以外的其他API也很重要。無論這種做法出現的原因是什麼,您實際上並不需要在現代瀏覽器中堅持使用Ajax或WebSockets。

+0

謝謝,這就是我正在尋找的答案!我知道我忽略了一些東西,但我無法指責它。我從來沒有想過,多線程的缺乏會使整個事情成爲一個無關緊要的問題。 – user2295759

+0

奇怪的是,在那個小提琴中,我從來沒有得到一個「打開」警報:( –

+0

@CiprianTomoiaga什麼瀏覽器?在你的控制檯中,你是否看到任何網絡錯誤無法到達'echo.websocket.org'?它仍然適用於我在Chrome中。 – apsillers

相關問題