JavaScript 編寫線程代碼引用Concurrent.Thread.js

JavaScript 編寫線程代碼引用Concurrent.Thread.js下載地址

http://jsthread.sourceforge.net/cgi-bin/wiki/wiki.cgi#p0

馬上來下載和使用源碼吧!假定你已經將下載的源碼保存到一個名爲Concurrent.Thread.js的文件夾裏,在進行任何操作之前,先運行如下程序,這是一個很簡單的功能實現:

<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/javascript">
Concurrent.Thread.create(function(){
var i = 0;
while ( 1 ) {
document.body.innerHTML += i++ + "<br>";
}
});
</script>

執行這個程序將會順序顯示從0開始的數字,它們一個接一個出現,你可以滾屏來看它。現在讓我們來仔細研究一下代碼,他應用while(1)條件製造了一個不會中止的循環,通常情況下,象這樣不斷使用一個並且是唯一一個線程的JavaScript程序會導致瀏覽器看起來象凍結了一樣,自然也就不會允許你滾屏。那麼爲什麼上面的這段程序允許你這麼做呢?關鍵之處在於while(1)上面的那條Concurrent.Thread.create()語句,這是這個庫提供的一個方法,它可以創建一個新線程。被當做參數傳入的函數在這個新線程裏執行,讓我們對程序做如下微調:

<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/javascript">
function f ( i ){
while ( 1 ) {
document.body.innerHTML += i++ + "<br>";
}
}
Concurrent.Thread.create(f, 0);
Concurrent.Thread.create(f, 100000);
</script>

在這個程序裏有個新函數f()可以重複顯示數字,它是在程序段起始定義的,接着以f()爲參數調用了兩次create()方法,傳給create()方法的第二個參數將會不加修改地傳給f()。執行這個程序,先會看到一些從0開始的小數,接着是一些從100,000開始的大數,然後又是接着前面小數順序的數字。你可以觀察到程序在交替顯示小數和大數,這說明兩個線程在同時運行。

讓我來展示Concurrent.Thread的另外一個用法。上面的例子調用create()方法來創建新線程。不調用庫裏的任何APIs也有可能實現這個目的。例如,前面那個例子可以這樣寫:

<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/x-script.multithreaded-js">
var i = 1;
while ( 1 ) {
document.body.innerHTML += i++ + "<br>";
}
</script>

在script 標籤內,很簡單地用JavaScript寫了一個無窮循環。你應該注意到標籤內的type屬性,那裏是一個很陌生的值(text/x- script.multithreaded-js),如果這個屬性被放在script標籤內,那麼Concurrent.Thread就會在一個新的線程內執行標籤之間的程序。你應當記住一點,在本例一樣,必須將Concurrent.Thread庫包含進來。

有了Concurrent.Thread,就有可能自如的將執行環境在線程之間進行切換,即使你的程序很長、連續性很強。我們可以簡要地討論下如何執行這種操作。簡言之,需要進行代碼轉換。粗略地講,首先要把傳遞給create()的函數轉換成一個字符串,接着改寫直至它可以被分批分次執行。然後這些程序可以依照調度程序逐步執行。調度程序負責協調多線程,換句話說,它可以在適當的時候做出調整以便每一個修改後的函數都會得到同等機會運行。 Concurrent.Thread實際上並沒有創建新的線程,僅僅是在原本單線程的基礎上模擬了一個多線程環境。

雖然轉換後的函數看起來是運行在不同的線程內,但是實際上只有一個線程在做這所有的事情。在轉換後的函數內執行同步通信仍然會造成瀏覽器凍結,你也許會認爲以前的那些問題根本就沒有解決。不過你不必耽心,Concurrent.Thread提供了一個應用JavaScript 的異步通信方式實現的定製通信庫,它被設計成當一個線程在等待服務器的響應時允許其它線程運行。這個通信庫存於 Concurrent.Thread.Http下。它的用法如下所示:

<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/x-script.multithreaded-js">
var req = Concurrent.Thread.Http.get(url, ["Accept", "*"]);
if (req.status == 200) {
alert(req.responseText);
} else {
alert(req.statusText);
}
</script>

get()方法,就像它的名字暗示的那樣,可以通過HTTP的GET方法獲得指定URL的內容,它將目標URL作爲第一個參數,將一個代表HTTP請求頭的數組作爲可選的第二個參數。get()方法與服務器交互,當得到服務器的響應後就返回一個XMLHttpRequest對象作爲返回值。當get()方法返回時,已經收到了服務器響應,所以就沒必要再用回調函數接收結果。自然,也不必再耽心當程序等待服務器的響應時瀏覽器凍結的情況了。另外,還有一個 post()方法可以用來發送數據到服務器:

<script type="text/javascript" src="Concurrent.Thread.js"></script>
<script type="text/x-script.multithreaded-js">
var req = Concurrent.Thread.Http.post(url, "key1=val1&key2=val2");
alert(req.statusText);
</script>

post()方法將目的URL作爲第一個參數,要發送的內容作爲第二個參數。像get()方法那樣,你也可以將請求頭作爲可選的第三個參數。

如果你用這個通信庫實現了第一個例子當中的getArticle()方法,那麼你很快就能應用文章開頭示例的那種簡單的方法寫出getArticleWithCache(),backgroundLoad ()以及其它調用了getArticle()方法的函數了。即使是那版backgroundLoad()正在讀文章數據,照例還有另外一個線程可以對用戶請求做出響應,瀏覽器因此也不會凍結。現在,你能理解在JavaScript中應用多線程有多實用了?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章