為了處理這種異步調用,Mochikit從Python的Twisted框架借來了Deferred這個類,並用它來處理AJAX的回調。AJAX的回調通常有兩種,成功加載時的回調與請求失敗的回調,IE8的XDomainRequest就有這兩種回調了,標准浏覽器的script與image也有這兩種回調,分別稱之為onload與onerror。Mochikit的Deferred實例就內置一個數組,每次包含這兩種回調,依次執行。Mochikit這偉大的遺產後來由dojo發揚光大了,至於怎麼用,自己google吧。
下面是我的框架對它的應用,我已把它整合到我的框架中:
復制代碼 代碼如下:
<!doctype html>
<html>
<head>
<title>異步操作例子 by 司徒正美</title>
<meta charset="utf-8"/>
<meta content="IE=8" http-equiv="X-UA-Compatible"/>
<meta name="keywords" content="異步操作例子 by 司徒正美" />
<meta name="description" content="異步操作例子 by 司徒正美" />
<%= 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>
</head>
<body>
</body>
</html>
後台:
復制代碼 代碼如下:
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
在日本一博客提到這樣一個捕捉異步錯誤的例子:
復制代碼 代碼如下:
function throwError(){
throw new Error('ERROR');
}
try{
setTimeout(throwError, 3000);
} catch(e){
alert(e);
}
看來try...catch是無法捕捉這種形式的錯誤,window.onerror可以,但好像只有IE與FF支持。如果用Deferred來處理,就簡單了!
復制代碼 代碼如下:
dom.Deferred.next(function () {
throw new Error("錯誤")
}).wait(1).error(function(e){
alert(e instanceof Error)
});
列隊處理。由於是使用了異步,因此不會阻塞頁面的演染。
復制代碼 代碼如下:
<!doctype html>
<html>
<head>
<title>異步操作例子 by 司徒正美</title>
<meta charset="utf-8"/>
<meta content="IE=8" http-equiv="X-UA-Compatible"/>
<meta name="keywords" content="異步操作例子 by 司徒正美" />
<meta name="description" content="異步操作例子 by 司徒正美" />
<%= 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 += "司徒正美"+i+"<br/>"
});
});
/*結果
0
a
司徒正美0
1
司徒正美1
2
c
司徒正美2
3
d
司徒正美3
4
e
司徒正美4
5
f
司徒正美5
6
g
司徒正美6
7
h
司徒正美7
8
i
司徒正美8
9
j
司徒正美9
*/
</script>
</head>
<body>
<div id="aaa"></div>
</body>
</html>