网络编程 
首页 > 网络编程 > 浏览文章

javascript异步编程

(编辑:jimmy 日期: 2025/5/13 浏览:3 次 )
就好像排队,前面的人忙着忙着突然上厕所了,后面的人阻塞在这里,因此我们就需要让前面的人死到一边去,让后面的人跟进……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>

上一篇:javascript调试说明
下一篇:js执行时间查看器
一句话新闻
一文看懂荣耀MagicBook Pro 16
荣耀猎人回归!七大亮点看懂不只是轻薄本,更是游戏本的MagicBook Pro 16.
人们对于笔记本电脑有一个固有印象:要么轻薄但性能一般,要么性能强劲但笨重臃肿。然而,今年荣耀新推出的MagicBook Pro 16刷新了人们的认知——发布会上,荣耀宣布猎人游戏本正式回归,称其继承了荣耀 HUNTER 基因,并自信地为其打出“轻薄本,更是游戏本”的口号。
众所周知,寻求轻薄本的用户普遍更看重便携性、外观造型、静谧性和打字办公等用机体验,而寻求游戏本的用户则普遍更看重硬件配置、性能释放等硬核指标。把两个看似难以相干的产品融合到一起,我们不禁对它产生了强烈的好奇:作为代表荣耀猎人游戏本的跨界新物种,它究竟做了哪些平衡以兼顾不同人群的各类需求呢?
友情链接:杰晶网络 DDR爱好者之家 南强小屋 黑松山资源网 白云城资源网 网站地图 SiteMap