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>