Heim > Web-Frontend > js-Tutorial > Hauptteil

小试JavaScript多线程第1/2页_javascript技巧

PHP中文网
Freigeben: 2016-05-16 18:58:27
Original
895 Leute haben es durchsucht

这两天一直在弄ajax,用多了才发现了ajax 的cache问题,请求了好多次,得到了确是相同的结果,经常我想在请求的同时去做一些其它的事情,我在想javascript里有没有办法用多线程,经过在网上查找找到了结果。

法宝就是Concurrent.Thread这个家伙,其实是一个js库,你可以从网站下载源代码.如何使用呢?
很简单
Concurrent.Thread.create(f, a1, a2, ...) f为你要调用的函数,a1,a2为该函数的参数,这样创建了一个线程,你可以同时创建多个,他们会同时去执行,这个库同时提供 了很多的方法,类似其它语言里的Thread使用方法,如Concurrent.Thread.stop();等。具体去网站去了解。


<html> 
<body> 
<script type="text/javascript" src="Concurrent.Thread.Compiler.js"></script> 
<script type="text/javascript"> 
function hello ( ) { 
document.body.innerHTML += "H"; 
document.body.innerHTML += "e"; 
document.body.innerHTML += "l"; 
document.body.innerHTML += "l"; 
document.body.innerHTML += "o"; 
document.body.innerHTML += ","; 
document.body.innerHTML += " "; 
document.body.innerHTML += "w"; 
document.body.innerHTML += "o"; 
document.body.innerHTML += "r"; 
document.body.innerHTML += "l"; 
document.body.innerHTML += "d"; 
document.body.innerHTML += "!"; 
} 
Concurrent.Thread.create(hello); 
</script> 
</body> 
</html>
Nach dem Login kopieren


作者 Daisuke Maki译者 张凯峰
虽然有越来越多的网站在应用AJAX技术进行开发,但是构建一个复杂的AJAX应用仍然是一个难题。造成这些困难的主要原因是什么呢?是与服务器的异步通信问题?还是GUI程序设计问题呢?通常这两项工作都是由桌面程序来完成的,那究竟为何开发一个可以实现同样功能的AJAX应用就这么困难呢?
AJAX 开发中的难题
让我们通过一个简单的例子来认识这个问题。假设你要建立一个树形结构的公告栏系统(BBS),它可以根据用户请求与服务器进行交互,动态加载每篇文章的信息,而不是一次性从服务器载入所有文章信息。每篇文章有四个相关属性:系统中可以作为唯一标识的ID、发贴人姓名、文章内容以及包含其所有子文章 ID的数组信息。首先假定有一个名为getArticle()的函数可以加载一篇文章信息。该函数接收的参数是要加载文章的ID,通过它可从服务器获取文章信息。它返回的对象包含与文章相关的四条属性:id,name,content和children。例程如下:

function ( id ) { 
var a = getArticle(id); 
document.writeln(a.name + " 
" + a.content); 
}
Nach dem Login kopieren

然而你也许会注意到,重复用同一个文章ID调用此函数,需要与服务器之间进行反复且无益的通信。想要解决这个问题,可以考虑使用函数 getArticleWithCache(),它相当于一个带有缓存能力的getArticle()。在这个例子中,getArticle()返回的数据只是作为一个全局变量被保存下来:

var cache = {}; 
function getArticleWithCache ( id ) { 
if ( !cache[id] ) { 
cache[id] = getArticle(id); 
} 
return cache[id]; 
}
Nach dem Login kopieren

现在已将读入的文章缓存起来,让我们再来考虑一下函数backgroundLoad(),它应用我们上面提到的缓存机制加载所有文章信息。其用途是,当读者在阅读某篇文章时,从后台预加载它所有子文章。因为文章数据是树状结构的,所以很容易写一个递归的算法来遍历树并且加载所有的文章:

function backgroundLoad ( ids ) { 
for ( var i=0; i < ids.length; i++ ) { 
var a = getArticleWithCache(ids[i]); 
backgroundLoad(a.children); 
} 
}
Nach dem Login kopieren

backgroundLoad ()函数接收一个ID数组作为参数,然后通过每个ID调用前面定义过的getArticldWithCache()方法,这样就把每个ID对应的文章缓存起来。之后再通过已加载文章的子文章ID数组递归调用backgroundLoad()方法,如此整个文章树就被缓存起来。
到目前为止,一切似乎看起来都很完美。然而,只要你有过开发AJAX应用的经验,你就应该知晓这种幼稚的实现方法根本不会成功,这个例子成立的基础是默认 getArticle()用的是同步通信。可是,作为一条基本原则,JavaScript要求在与服务器进行交互时要用异步通信,因为它是单线程的。就简单性而言,把每一件事情(包括GUI事件和渲染)都放在一个线程里来处理是一个很好的程序模型,因为这样就无需再考虑线程同步这些复杂问题。另一方面,他也暴露了应用开发中的一个严重问题,单线程环境看起来对用户请求响应迅速,但是当线程忙于处理其它事情时(比如说调用getArticle()),就不能对用户的鼠标点击和键盘操作做出响应。
如果在这个单线程环境里进行同步通信会发生什么事情呢?同步通信会中断浏览器的执行直至获得通信结果。在等待通信结果的过程中,由于服务器的调用还没有完成,线程会停止响应用户并保持锁定状态直到调用返回。因为这个原因,当浏览器在等待服务器响应时它不能对用户行为作出响应,所以看起来像是冻结了。当执行 getArticleWithCache()和backgroundLoad()会有同样的问题,因为它们都是基于getArticle()函数的。由于下载所有的文章可能会耗费很可观的一段时间,因此对于backgroundLoad()函数来说,浏览器在此段时间内的冻结就是一个很严重的问题——既然浏览器都已经冻结,当用户正在阅读文章时就不可能首先去执行后台预加载数据,如果这样做连当前的文章都没办法读。
如上所述,既然同步通信在使用中会造成如此严重的问题,JavaScript就把异步通信作为一条基本原则。因此,我们可以基于异步通信改写上面的程序。 JavaScript要求以一种事件驱动的程序设计方式来写异步通信程序。在很多场合中,你都必须指定一个回调程序,一旦收到通信响应,这个函数就会被调用。例如,上面定义的getArticleWithCache()可以写成这样:

var cache = {}; 
function getArticleWithCache ( id, callback ) { 
if ( !cache[id] ) { 
callback(cache[id]); 
} else { 
getArticle(id, function( a ){ 
cache[id] = a; 
callback(a); 
}); 
} 
}
Nach dem Login kopieren


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage