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中应用多线程有多实用了?