I have been working on ajax for the past two days. After using it a lot, I discovered the cache problem of ajax. I requested it many times and got the same result. I often want to do other things while requesting. I was wondering if there was a way to use multi-threading in JavaScript, and I found the result after searching online.
The magic weapon is Concurrent.Thread, which is actually a js library. You can download the source code from the website. How to use it?
It’s very simple
Concurrent.Thread.create(f, a1, a2, ...) f is the function you want to call, a1, a2 are the parameters of the function. This creates a thread. You can create multiple ones at the same time, and they will be executed at the same time. This library provides many methods at the same time. , similar to the Thread usage methods in other languages, such as Concurrent.Thread.stop(); etc. Go to the website to find out specifically.
<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>
Author Daisuke Maki Translator Zhang Kaifeng
Although more and more websites are developed using AJAX technology, building A complex AJAX application is still a difficult problem. What are the main reasons for these difficulties? Is it an asynchronous communication issue with the server? Or is it a GUI programming issue? Usually these two tasks are completed by desktop programs, so why is it so difficult to develop an AJAX application that can achieve the same function?
Difficulties in AJAX development
Let us understand this problem through a simple example. Suppose you want to build a tree-structured bulletin board system (BBS), which can interact with the server according to user requests and dynamically load the information of each article, instead of loading all article information from the server at once. Each article has four related attributes: an ID that can be used as a unique identifier in the system, the name of the poster, the content of the article, and an array information containing the IDs of all its sub-articles. First, assume that there is a function named getArticle() that can load an article information. The parameter received by this function is the ID of the article to be loaded, through which the article information can be obtained from the server. The object it returns contains four attributes related to the article: id, name, content and children. The routine is as follows:
function ( id ) { var a = getArticle(id); document.writeln(a.name + " " + a.content); }
However, you may notice that calling this function repeatedly with the same article ID requires repeated and unhelpful communication with the server. To solve this problem, you can consider using the function getArticleWithCache(), which is equivalent to getArticle() with caching capabilities. In this example, the data returned by getArticle() is only saved as a global variable:
var cache = {}; function getArticleWithCache ( id ) { if ( !cache[id] ) { cache[id] = getArticle(id); } return cache[id]; }
Now that the read articles have been cached, let us consider the function backgroundLoad( ), which loads all article information using the caching mechanism we mentioned above. Its purpose is to preload all its sub-articles from the background when a reader reads an article. Because the article data is structured in a tree, it is easy to write a recursive algorithm to traverse the tree and load all articles:
function backgroundLoad ( ids ) { for ( var i=0; i < ids.length; i++ ) { var a = getArticleWithCache(ids[i]); backgroundLoad(a.children); } }
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); }); } }