JavaScript Asynchronous Programming _javascript Tips

Source: Internet
Author: User
Tags script tag
It's like waiting in line, the person in front is busy doings wherever to go to the toilet suddenly, the person behind is blocked here, so we need to let the person in front die to side, let the person follow up after ... Ajax is the concept, the request continues, but we can do other things.

This functionality is implemented in JavaScript by a function settimeout from the BOM, but the associated DOM operation also provides a series of implementations. such as XMLHttpRequest object and script tag onreadystatechange callback, image of the onload and OnError callback, the onload,dom element of the IFrame event callback, HTML5 cross-domain message delivery postmessage,quicktime and Flash Object loading ...

SetTimeout's 0-second delay was particularly popular at home in previous years, but SetTimeout is the slowest of all delays, at least 10 milliseconds, and if settimeout is used to develop special effects, the effect will run slower. Here is a performance test:
<!doctype html> <ptml lang= "en" > <pead> <title>async Performance test</title>-<meta charset= "gb2312" > <style> Pre {background-color: #eeeeee; padding:20px; } div.test {margin:20px; padding:10px; Border:solid black 1px; } </style> </pead> <body> <div class= "Test" > <p>settimeout (Slow, takes about sec) & lt;/h3> <pre class= "source" > Function Async (callback) {settimeout (callback, 0); } </pre> <p> <input type= "button" value= "Run" onclick= "Runtest (this.parentNode.parentNode)" > </p > </div> <div class= "Test" > <p>img.onerror (Data:uri) </p> <pre class= "source" > Fu Nction Async (callback) {var img = new Image; Img.addeventlistener (' Error ', callback, false); IMG.SRC = ' Data:,foo '; } </pre> <p> <input type= "button" value= "Run" onclick= "Runtest (this.parentNode.parentNode)" > </p > </div> <div class= "Test" > <p>script.onreadystatechange</p> <pre class= "source" > Function Async ( Callback) {var script = document.createelement ("script"); Script.type = "Text/javascript"; Script.src = "javascript:"; Script.onreadystatechange = function () {document.body.removeChild (script); Callback (); } document.body.appendChild (script); } </pre> <p> <input type= "button" value= "Run" onclick= "Runtest (this.parentNode.parentNode)" > </p > </div> <div class= "Test" > <p>script.onload (Data:uri) </p> <pre class= "source" > Function Async (callback) {var script = document.createelement (' script '); Script.onload = function () {document.body.removeChild (script); Callback (); } script.src = ' Data:text/javascript, '; Document.body.appendChild (script); } </pre> <p> <input type= "button" value= "Run" onclick= "Runtest (this.parentNode.parentNode)" > </p > </div> <diV class= "Test" > <p>xhr.onreadystatechange (data:text/plain,foo) </p> <pre class= "source" > Function Async (callback) {var xhr = new XMLHttpRequest; Xhr.open (' Get ', ' Data:text/plain,foo ', true); Xhr.onreadystatechange = function () {xhr.onreadystatechange = null; Callback (); }; Xhr.send (NULL); } </pre> <p> <input type= "button" value= "Run" onclick= "Runtest (this.parentNode.parentNode)" > </p > </div> <div class= "Test" > <p>self.postMessage</p> <pre class= "source" > function Async (callback) {var n = ++async.count; Window.addeventlistener (' message ', function (e) {if (E.data = = N) {window.removeeventlistener (' message '), Arguments.callee,false); Callback (); }},false); Window.postmessage (n, Location.protocol + "//" + location.host); } async.count = 0; </pre> <p> <input type= "button" value= "Run" onclick= "Runtest (this.parentNode.parentNode)" > </p& Gt </div> <script> function Runtest (div) {var pre = Div.getelementsbytagname (' pre ') [0]; Eval (pre.textcontent | | pre.innertext); Load Async function var p = div.getelementsbytagname (' P ') [0]; var t = new Date, n = 1000, i = 0, flag = true; try {test (); catch (e) {} settimeout (function () {if (flag) p.innerhtml = ' failed '; flag = false}, 200); function Test () {if (i++ < n) {async (test); if (flag && i = = 2) {p.innerhtml = ' running '; Flag = false; } else {p.innerhtml = "Average delay was" + (new Date-t)/n + "MS, over" + + N + "iterations.";}} </script> </body> </ptml>
[Ctrl + A All SELECT Note: If the need to introduce external JS need to refresh to perform]

Chromium Safari Firefox Opera 10.10 Opera 10.50
SetTimeout 4.32ms 10.201ms 10.302ms 10.38ms 9.876ms
Img.onerror 0.199ms 0.678ms 0.201ms 0.058ms 0.575ms
Script.onreadystatechange Fail Fail Fail Fail Fail
Script.onload 0.414ms 0.138ms 0.414ms Fail Fail
Xhr.onreadystatechange Fail 0.622ms Fail 0.078ms 0.079ms
Self.postmessage 0.096ms 0.123ms 0.112ms 0.049ms 0.094ms

To handle this asynchronous invocation, MochiKit borrowed the deferred class from the Python twisted framework and used it to handle Ajax callbacks. Ajax callbacks usually have two kinds, the successful load callback and request failed callback, IE8 Xdomainrequest have these two callbacks, standard browser script and image also have these two callbacks, respectively called the OnLoad and onerror. MochiKit's deferred instance is built into an array, each containing both callbacks, executed sequentially. MochiKit this great legacy was later carried forward by Dojo, as for how to use, Google it.

The following is the application of my framework to it, which I have incorporated into my framework:

Copy Code code as follows:

<!doctype html>
<title> Asynchronous Operation example by Masaki </title>
<meta charset= "Utf-8"/>
<meta content= "ie=8" http-equiv= "x-ua-compatible"/>
<meta name= "keywords" content= "Asynchronous operation example by Masaki"/>
<meta name= "description" content= "Asynchronous operation example by Masaki"/>
<%= Javascript_include_tag "Dom.js"%>
<%= javascript_tag "Window._token = ' #{form_authenticity_token} '" If Actioncontroller::base.allow_forgery_ Protection%>
<script type= "Text/javascript" charset= "Utf-8" >
Dom.ready (function () {
Dom.require ("Ajax");
Dom.ajax ({method: Post),
Async:true,
DataType: "Text",
Data:{authenticity_token:window._token}
}). Next (function (a) {
Alert (a)
});
Dom.jsonp ({url: "Http://del.icio.us/feeds/json/fans/stomita"}). Next (function (JSON) {
Alert (JSON)
}). Error (function (e) {
Alert (e)
});
});
</script>
<body>
</body>

Background:
Copy Code code as follows:

Class HomeController < Applicationcontroller
def index
If REQUEST.XHR?
name = Params[:name]
Puts "-------------"
Render:text => "<p>the time is <b>" + DateTime.now.to_s + "</b></p>"
End
End
End

A blog in Japan mentions such an example of catching an asynchronous error:
Copy Code code as follows:

function ThrowError () {
throw new error (' Error ');
}
try{
SetTimeout (ThrowError, 3000);
catch (e) {
Alert (e);
}

It seems that Try...catch is unable to capture this form of error, Window.onerror can, but seems to have only IE and FF support. If you use deferred to deal with, it is simple!
Copy Code code as follows:

Dom. Deferred.next (function () {
throw new error ("Error")
). Wait (1). Error (function (e) {
Alert (e instanceof Error)
});

Queue processing. Because it is used asynchronously, the page is not blocked from being dyed.
Copy Code code as follows:

<!doctype html>
<title> Asynchronous Operation example by Masaki </title>
<meta charset= "Utf-8"/>
<meta content= "ie=8" http-equiv= "x-ua-compatible"/>
<meta name= "keywords" content= "Asynchronous operation example by Masaki"/>
<meta name= "description" content= "Asynchronous operation example by Masaki"/>
<%= Javascript_include_tag "Dom.js"%>
<script type= "Text/javascript" charset= "Utf-8" >
Dom.require ("deferred");
Dom.require ("Query");
Dom.ready (function () {
var a = dom ("#aaa") [0];
Dom. Deferred.loop (10,function (i) {
a.innerhtml + + i+ "<br/>"
});
Dom. Deferred.loop (10,function (i) {
A.innerhtml + + string.fromcharcode (i+97) + "<br/>"
});
Dom. Deferred.loop (10,function (i) {
a.innerhtml = "Masaki" +i+ "<br/>"
});
});
/* Results
0
A
Masaki 0
1

Masaki 1
2
C
Masaki 2
3
D
Masaki 3
4
E
Masaki 4
5
F
Masaki 5
6
G
Masaki 6
7
H
Masaki 7
8
I
Masaki 8
9
J
Masaki 9
*/
</script>
<body>
<div id= "AAA" ></div>
</body>

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.