JavaScript 編寫線程代碼引用Concurrent.Thread.js下載地址 javascript
http://jsthread.sourceforge.net/cgi-bin/wiki/wiki.cgi#p0 java
立刻來下載和使用源碼吧!假定你已經將下載的源碼保存到一個名爲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> post
在script 標籤內,很簡單地用JavaScript寫了一個無窮循環。你應該注意到標籤內的type屬性,那裏是一個很陌生的值(text/x- script.multithreaded-js),若是這個屬性被放在script標籤內,那麼Concurrent.Thread就會在一個新的線程內執行標籤之間的程序。你應當記住一點,在本例同樣,必須將Concurrent.Thread庫包含進來。 url
有了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中應用多線程有多實用了?