JS---js multithreaded programming of web development

Source: Internet
Author: User
Tags script tag

    1. The challenges of AJAX development
    2. Try multithreaded Programming
    3. Want to know more
    4. About the author

Reprint Annotated Source: Http://www.infoq.com/cn/articles/js_multithread

While more and more websites are being developed using AJAX technology, building a complex AJAX application is still a challenge. What is the main cause of these difficulties? is an asynchronous communication problem with the server? Or the GUI programming problem? Usually these two tasks are done by a desktop program, so why is it so difficult to develop an AJAX application that can do the same thing?

The challenges of AJAX development

Let's take a simple example to understand the problem. Suppose you want to create a tree-structured bulletin board system (BBS) that dynamically loads information about each article, instead of loading all the article information from the server at once, based on user requests to interact with the server. Each article has four related attributes: An ID that can be uniquely identified in the system, the name of the sender, the content of the article, and an array of information that contains all of its child article IDs. First assume that there is a function named Getarticle () that can load an article information. The parameter that the function receives is the ID of the article to load, through which you can get the article information from the server. The object it returns contains four properties related to the article: Id,name,content and children. The routines are as follows:

function (ID) {     var a = getArticle (ID);     

You may notice, however, that this function is called repeatedly with the same Article ID and requires repeated and unhelpful communication with the server. To solve this problem, consider using the function Getarticlewithcache (), which is equivalent to a getarticle () with a cache capability. 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);     }     

Now that you have cached the read-in article, let's consider the function backgroundload (), which loads all the article information using the caching mechanism we mentioned above. Its purpose is to pre-load all of its sub-articles from the background when the reader is reading an article. Because the article data is tree structured, it is easy to write a recursive algorithm to traverse the tree and load all the articles:

function Backgroundload (IDs) {for     (var i=0; i < ids.length; i++) {         var a = Getarticlewithcache (Ids[i]); 
   backgroundload (A.children);     

The Backgroundload () function receives an array of IDs as parameters, and then invokes the previously defined Getarticldwithcache () method with each ID, thus caching the article corresponding to each ID. The Backgroundload () method is then recursively called through the child article ID array of the loaded article, so that the entire article tree is cached.

So far, everything seems to be perfect. However, as long as you have experience in developing AJAX applications, you should be aware that this naïve implementation is not successful at all, and this example is based on the default getArticle () using synchronous communication. However, as a basic principle, JavaScript requires asynchronous communication when interacting with the server because it is single-threaded. In terms of simplicity, it is a good program model to put everything (including GUI events and rendering) in one thread, because it eliminates the complexity of thread synchronization. On the other hand, he also exposes a serious problem in application development, where a single-threaded environment appears to respond quickly to user requests, but when the thread is busy with other things (such as calling Getarticle ()), it cannot respond to the user's mouse clicks and keyboard actions.

What happens if I do synchronous communication in this single-threaded environment? Synchronous communication interrupts the execution of the browser until the communication results are obtained. In the process of waiting for the result of the communication, the thread stops responding to the user and remains locked until the call returns because the server's call is not completed. For this reason, when the browser waits for the server to respond, it cannot respond to user behavior, so it looks like it is frozen. The same problem occurs when executing Getarticlewithcache () and backgroundload () because they are all based on the getarticle () function. Since downloading all the articles can take a considerable amount of time, for the Backgroundload () function, the browser freezes during this time is a very serious problem-since the browser has been frozen, when the user is reading the article, it is impossible to first to perform background preloading data, If you do this, you won't be able to read the current article.

As mentioned above, since synchronous communication can cause such serious problems in use, JavaScript uses asynchronous communication as a basic principle. Therefore, we can rewrite the above program based on asynchronous communication. JavaScript requires an event-driven programming approach to write asynchronous communication programs. In many cases, you must specify a callback program that will be called once the communication response is received. For example, the Getarticlewithcache () defined above can be written like this:

var cache = {}; function Getarticlewithcache (ID, callback) {     if (!cache[id]) {         callback (Cache[id]);     } else {         getartic Le (ID, function (a) {             cache[id] = A;             Callback (a);         });     

The program also calls the Getarticle () function internally. It should be noted, however, that this version of the Getarticle () function designed for asynchronous communication receives a function as the second parameter. When this getarticle () function is called, it is the same as before to send a request to the server, the difference is that the function will now return quickly rather than wait for the response of the server. This means that when execution is handed back to the caller, there is no response from the server. As a result, the thread can perform other tasks until the server responds, and the callback function is called at this point. Once the server responds, the second parameter of GetArticle () is called as a pre-defined callback function, and the return value of the server is its parameter. Similarly, Getarticlewithcache () has to make some changes, defining a callback parameter as its second argument. This callback function is called in the callback function passed to Getarticle (), so it can be executed at the end of the server communication.

You may already think that the above changes are quite complex, but the changes to the Backgroundload () function will be more complex and should be rewritten to handle the callback function:

function Backgroundload (IDs, callback) {     var i = 0;     function L () {         if (I < ids.length) {             getarticlewithcache (ids[i++], function (a) {                 backgroundload (A.chil dren, L);             });         } else {             callback ();         }     }     

The modified backgroundload () function seems to be far from the one we used to be, but the functions they have implemented are not the same. This means that both functions accept an array of IDs as arguments, call Getarticlewithcache () for each element in the array, and then apply a recursive call to Backgroundload () that has obtained the child article ID. But the same is the circular access of the array, the new function is not very well recognized, the previous program is a For loop statement completed. Why are the two sets of functions that implement the same function so different?

The difference stems from the fact that any function must return immediately after encountering the need to communicate with the server, such as Getarticlewithcache (). Unless the original function is not in execution, the callback function that should accept the server response cannot be called. For JavaScript, it is not possible to break a program during a loop and continue executing a program from that breakpoint at a later time, such as a for statement. Therefore, this example uses recursive pass-through callback function to implement loop structure instead of a traditional loop statement. For those who are familiar with continuous delivery style (CPS), this is a manual implementation of CPS, because it is not possible to use the cyclic syntax, so even a simple procedure such as the one mentioned above is very complex. The problem with event-driven programming is control-flow problems: loops and other control-flow expressions can be difficult to understand.

Here's another question: if you convert a function that does not apply asynchronous communication to a function that uses asynchronous communication, then the overridden function will need a callback function as a new parameter, which poses a big problem for existing APIs because the internal changes do not confine the influence to the internal, It is a change of APIs that lead to overall confusion and other users of the API.

What is the root cause of these problems? Yes, it is the JavaScript single-threaded mechanism that causes these problems. Executing asynchronous communication in a single thread requires event-driven programming and complex statements. If a program waits for a response from the server, there is another thread that can handle the user's request, which is not required for this complex technique.

Try multithreaded Programming

Let me introduce concurrent.thread, a library that allows JavaScript to be multithreaded, and it can be used to greatly alleviate the difficulties associated with asynchronous communication in AJAX development as mentioned above. This is a free software library written in JavaScript, and it is subject to the two Protocols of Mozilla Public License and the GNU General Public License. You can download the source code from their website.

Download and use the source code now! Assuming that you have saved the downloaded source to a folder named Concurrent.Thread.js, run the following program before any operation, which is a very simple feature implementation:

<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>

The execution of this program will show the numbers starting from 0 sequentially, they appear one after another, you can scroll to see it. Now let's take a closer look at the code, and he's using the while (1) condition to create a loop that doesn't stop, and typically, a JavaScript program that constantly uses one and only one thread will cause the browser to look like it freezes, and it will not allow you to roll the screen. So why does the program above allow you to do this? The key is that the Concurrent.Thread.create () statement above the while (1), which is a method provided by this library, can create a new thread. The function passed as a parameter is executed in this new thread, so let's fine-tune the program as follows:

<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);     

In this program there is a new function f () can repeat the number, it is defined in the beginning of the program section, and then the F () for the parameter call two times the Create () method, the second parameter passed to the Create () method will be passed to F () without modification. To execute this program, you will see some decimal numbers starting with 0, followed by a number of large numbers starting from 100,000, followed by a decimal order. You can observe that the program is alternately displaying decimals and large numbers, which means that two threads are running at the same time.

Let me show you another use of concurrent.thread. The example above calls the Create () method to make a new thread. It is also possible to do this without invoking any APIs in the library. For example, the previous example could be written like this:

<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>";     

Within the script tag, it's easy to write an infinite loop with JavaScript. You should notice the type attribute inside the tag, there is a very strange value (text/x-script.multithreaded-js), if this attribute is placed inside the script tag, Then Concurrent.thread will execute the program between the tags within a new thread. You should keep in mind that, as in this example, the Concurrent.thread library must be included.

With Concurrent.thread, it's possible to switch between the execution environment threads, even if your program is long and consistent. We can briefly discuss how to perform this operation. In short, code conversions are required. Roughly speaking, you first convert the function passed to create () to a string, and then rewrite it until it can be executed in batches. These programs can then be progressively executed in accordance with the scheduler. The scheduler is responsible for coordinating multi-threading, in other words, it can make adjustments at the appropriate time so that every modified function gets the same chance to run. Concurrent.thread actually did not create a new thread, only simulating a multithreaded environment on the basis of the original single thread.

Although the converted function appears to be running in a different thread, there is actually only one thread doing all of this. Performing synchronous communication within the converted function will still cause the browser to freeze, and you may think that the previous problems have not been solved at all. But you don't have to worry, Concurrent.thread provides a custom communication library that is implemented using JavaScript asynchronous communication, which is designed to allow other threads to run when a thread waits for a response from the server. This communication is in stock under Concurrent.Thread.Http. Its usage is as follows:

<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);     

The Get () method, as its name implies, can get the contents of the specified URL through the Get method of HTTP, which takes the destination URL as the first parameter and an array representing the HTTP request header as an optional second parameter. The Get () method interacts with the server and returns a XMLHttpRequest object as the return value when the response from the server is obtained. When the Get () method returns, the server response has been received, so there is no need to use the callback function to receive the result. Naturally, there is no need to worry about when the program waits for the server to respond when the browser freezes. In addition, there is a post () method that can be used to send data to the server:

<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>

The post () method takes the destination URL as the first parameter, and the content to be sent as the second parameter. Like the Get () method, you can also use the request header as an optional third parameter.

If you use this communication library to implement the Getarticle () method in the first example, you will soon be able to apply the simple method of writing Getarticlewithcache (), Backgroundload () in the beginning of the article. and other functions that call the Getarticle () method. Even if that version of Backgroundload () is reading the article data, as usual there is another thread that can respond to user requests and therefore the browser will not freeze. Now, can you understand how useful it is to apply multithreading in JavaScript?

Want to know more

I've introduced you to a library that you can apply multithreading to in JavaScript: Concurrent.thread. The content of this article is only a very elementary thing, if you want to know more in-depth, I recommend you to see the tutorial. It provides more content about concurrent.thread usage, and lists the documents that are available to advanced users, and is the most suitable material for getting started. It's also good to visit their website, where more information is available.

About the author

Daisuke Maki: After graduating from the Natural Science division of International Christian University (Bachelor of Arts), he also studied for a master's degree at Electro-communications University's Graduate School of Information. Ajax that specializes in web development and application JavaScript. He developed the Concurrent.thread. This design was applied in the financial year 2006 project Explatory software projects, guided by the Information Technology Promotion Agency (IPA) in Japan.

He currently has a master's degree in engineering and is enrolled for a doctorate at the Graduate School of Electro-communications University.

http://blog.csdn.net/huguohu2006/article/details/7787571

http://www.iteye.com/problems/7056 iframe

JS---js multithreaded programming of web development

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.