富贵资源网 Design By www.hznty.com
就好像排队,前面的人忙着忙着突然上厕所了,后面的人阻塞在这里,因此我们就需要让前面的人死到一边去,让后面的人跟进……AJAX就是这个概念,请求还在继续,但我们还可以做其他事。

javascript中实现这个功能的是来自BOM的一个函数setTimeout,但相关的DOM操作也提供了一系列实现。如XMLHttpRequest对象与script标签的onreadystatechange回调,image的onload与onerror回调,iframe的onload,DOM元素的事件回调,HTML5的跨域消息传送postMessage,QuickTime与flash对象的加载……

setTimeout的零秒延迟在前些年时间被国内宣扬得特别厉害,但setTimeout是所有延迟中最慢的,最少要花上10多毫秒,如果用setTimeout来开发特效,这特效会运行得比较慢。下面是一个性能测试:

[Ctrl+A 全选 注:引入外部Js需再刷新一下页面才能执行]
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

为了处理这种异步调用,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>

富贵资源网 Design By www.hznty.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
富贵资源网 Design By www.hznty.com