JavaScript asynchronous programming

Source: Internet
Author: User
Introduction JavaScript is a single-threaded scripting language. To prevent JavaScript code from being executed for too long, to block UI rendering or mouse event processing, an asynchronous programming mode is usually used. Let's take a look at the asynchronous programming mode of JavaScript. I .. SyntaxHighlighter. all ()

Introduction

JavaScript is a single-threaded scripting language. To prevent JavaScript code from being executed for too long, blocking UI rendering or mouse event processing, an asynchronous programming mode is usually used. Let's take a look at the asynchronous programming mode of JavaScript.

 

I. asynchronous programming mode of JavaScript

1.1 why asynchronous programming

As I said at the beginning, JavaScript is a single-threaded scripting language (this may be due to historical reasons or design for simplicity ). Its Single-threaded performance is that after all functions are executed from start to end, another function will be executed, interface updates, processing of mouse events, timers (setTimeout, setInterval, etc) you also need to queue before serial execution. If a piece of JavaScript is executed for a long time from start to end, any UI update will be blocked during execution, and the interface event processing will stop responding. In this case, asynchronous programming mode is required. The purpose is to scatter the code or enable I/O calls (such as AJAX) to run in the background, so that interface updates and event processing can run in a timely manner.

The following is an example of synchronous and asynchronous execution.
01
Id = "output">
02
 
03
Onclick = "updateSync
() "> Run
Sync
04
 
05
Onclick = "updateAsync
() "> Run
Async
06
 
07
Script
08
 
09
Function updateSync ()
{
10
For (var I
= 0; I <1000; I ++ ){
11
Document. getElementById ('output'). innerHTML
= I;
12
}
13
}
14
 
15
Function updateAsync ()
{
16
Var I
= 0;
17
 
18
Function updateLater ()
{
19
Document. getElementById ('output'). innerHTML
= (I ++ );
20
If (I
& Lt; 1000 ){
21
SetTimeout (updateLater,
0 );
22
}
23
}
24
 
25
UpdateLater ();
26
}
27
Script


Click "Run Sync" to call the updateSync synchronization function. The logic is very simple. The output node content of the loop body is I each time it is updated. If the language is in another multi-threaded model, you may see that the interface stops at a very fast speed from 0 to 999. However, in JavaScript, you will feel stuck when the button is pressed down, and then you will see a final result of 999 without any intermediate process, this is because the UI update is blocked when the updateSync function is running. The UI is updated only when it is terminated and exited. If you increase the running time of this function (for example, change the upper limit to 1 000 000), you will see a more obvious pause. When you click another button during the pause, there is no response, the click event of another button will be processed only after the end.

The other button "Run Async" will call the updateAsync function, which is an asynchronous function. At first glance, the logic is complicated, the function first declares a local variable I and the nested function updateLater (for details about embedded functions, see the first-class citizen-function in the JavaScript World), and then calls updateLater, in this function, the content of the output node is updated to I, and the updateLater function is executed asynchronously through setTimeout. After this function is run, you will see the quick update process from 0 to 999 on the UI interface. This is the result of asynchronous execution.

It can be seen that asynchronous programming in JavaScript is even a necessary programming mode.

 

Advantages and disadvantages of 1.2 asynchronous programming

The advantages of asynchronous programming are obvious. You can implement the effects of updating while running in the previous example, or use Asynchronous IO to make the UI run more smoothly, for example, if you use the asynchronous interface of XMLHTTPRequest to obtain network data and update the interface after the retrieval is complete, the UI update will not be blocked when data is obtained asynchronously. Asynchronous programming modes are fully used in the design of APIS for many HTML5 devices, such as W3C File System APIs, File APIs, Indexed Database APIs, Windows 8 APIs, and PhoneGap APIs, the Node. js api for server scripts.

Asynchronous programming also has some disadvantages, resulting in in-depth nested function calls, undermining the original simple logic and making the code hard to understand.

 

Ii. asynchronous programming interface design

 

2.1 W3C Native Interface

The W3C Native Interface is often designed in the form of callback functions and event triggers. The former directly imports the callback function as a parameter when calling an asynchronous function, and the latter binds the event processing function to the original object, when an asynchronous function fails, it generally does not throw an exception. Instead, it calls an error callback function or triggers an error event. In terms of semantics, the callback function is used to obtain the running result of a function, event triggers are usually used to indicate certain state changes (loading, errors, progress changes, received messages, and so on ). When developing small projects, individuals or teams can refer to these two forms of interface design.

 

Callback Function: for example, W3C File System API uses the callback function in the form of interfaces such as requesting Virtual File System instances and reading and writing files:

01
RequestFileSystem (TEMPORARY,
1024*1024, function (fs)
{
02
 
03
//
Asynchronously obtaining Virtual File System instance fs
04
 
05
Fs. root. getFile ("already_there.txt", null, function (f)
{
06
 
07
//
Obtained file already_there.txt
08
 
09
GetAsText (f. file ());
10
 
11
}, Function (err)
{
12
 
13
//
An error occurred while obtaining the file.
14
 
15
});
16
 
17
}, Function (err)
{
18
 
19
//
An error occurred while obtaining the virtual file system.
20
 
21
});
 

Event triggering: for example, W3C XMLHTTPRequest (AJAX) is implemented in the form of event triggering. When an AJAX request succeeds or fails, the onload and onerror events are triggered:

01
Var xhr
= New XMLHTTPRequest ();
02
 
03
Xhr. onload
= Function ()
{
04
 
05
//
Onload event triggered when loading is successful
06
 
07
};
08
 
09
Xhr. onerror
= Function ()
{
10
 
11
//
Onerror event triggered when loading fails
12
 
13
};
14
 
15
Xhr. open ('get ',
'/Get-ajax', true );
16
 
17
Xhr. send (null );
 

2.2 third-party asynchronous Interface Design

Writing code using interfaces in the form of callback functions brings about serious function nesting problems. Just like the famous LISP, a large number of controversial parentheses are introduced, the structure of code segments that are executed sequentially before and after is changed to a layer-by-layer structure, which affects the clarity of JavaScript code logic. To solve this problem, we need a better asynchronous Interface Design Scheme for logically sequential code execution, which is also sequential in form, rather than nested.

CommonJS is a well-known open-source JavaScript organization that aims to design standard interfaces unrelated to the JS environment and provide standard library functions similar to Ruby and Python. CommonJS has three interface proposals related to asynchronous programming modes: Promises/A, Promises/B, and Promises/D. Promise means commitment, which means to complete a task, tell whether the execution is successful, and return the result.

Here we will only introduce the simplest asynchronous interface Promises/A. When using A function of this interface, the return value of the function is A Promise object, which has three states: unfulfilled), meet the conditions (fulfilled), failure (failed), as the name suggests does not meet the condition state is the status of the asynchronous function just called, not actually executed, meet the condition is the status of the successful execution, failure is the status of execution failure. Its interface function also has only one:

Then (fulfilledHandler, errorHandler, progressHandler)

These three parameters are the callback functions that meet the conditions, fail, and progress changes. Their parameters correspond to the asynchronous call results respectively, and the return value of then is still a Promise object, this object contains the returned values of the callback function that was asynchronously called in the previous step. Therefore, it can be written in a chain to form the logic of sequential execution. For example, if W3C File System API adopts the Promises/A interface design, the example in section 2.1 can be written as follows:

01
RequestFileSystem (TEMPORARY,
1024*1024)
02
 
03
. Then (function (fs)
{
04
 
05
//
Asynchronously obtaining Virtual File System instance fs
06
 
07
Return fs. root. getFile ("already_there.txt", null );
08
 
09
})
10
 
11
. Then (function (f)
{
12
 
13
//
Obtained file already_there.txt
14
 
15
GetAsText (f. file ());
16
 
17
});


Is it clear?

There are many JS libraries that implement Promises/A interfaces, such as when. js, node-promise, promised-io, etc. The interface design for Microsoft Windows 8 Metro applications also adopts the same interface design. For details, see Asynchronious Programming in JavaScript with "Promises ".

 

2.3 asynchronous Synchronization

The third-party asynchronous interface solves the issue of inconsistent code logic and execution sequence to some extent, but it still makes the code difficult to understand in some cases. We also take the code in section 1.1 as an example. Even if you use the Promises API, updateAsync is not better understood. The function implemented by the Code is actually a simple loop + update function. At this time, some asynchronous synchronization is required to help implement the synchronization.

As the name suggests, asynchronous synchronization uses syntaxes to Implement Asynchronous calls. Here is a brief introduction to Lao Zhao's Jscex, which is a pure JavaScript library that can run in any browser or JavaScript environment. It not only supports Asynchronous Synchronous Programming syntax, it also supports parallel execution and other features. Use Jscex to rewrite the code in section 1.1.
01
Function updateAsync ()
{
02
Var update
= Eval (Jscex. compile ('async', function ()
{
03
 
04
For (var I
= 0; I <1000; I ++ ){
05
Document. getElementById ('output'). innerHTML
= I;
06
$ Await (Jscex. Async. sleep (0 ));//
Sleep 0 MS to make it asynchronous
07
}
08
 
09
}));
10

11
Update (). start ();
12
}


Update is a function compiled by Jscex. It returns a Jscex Task object and executes the Task by calling its start method. The logic of the Update function is almost the same as that of updateSync. $ await is a keyword added by Jscex to wait for the call result of an asynchronous task, Jscex. async. sleep is a built-in asynchronous task of Jscex. It is used to explicitly wait for several milliseconds. After this line of statements is added, the Jscex compiler generates asynchronous code to update the UI while computing, keep the code structure concise and clear.

 

Related Article

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.