javascript异步编程

 更新时间:2010年06月07日 23:24:24   作者:  
如果编程加入了时间的概念就一切变得非常复杂。通常我们的程序是飞快地解析执行,一毫秒紧接着一毫秒,从上至下地执行,这称之为同步。但如果我们想让后台的程序不等前面的程序执行,就执行呢,于是就有了异步的概念。
就好像排队,前面的人忙着忙着突然上厕所了,后面的人阻塞在这里,因此我们就需要让前面的人死到一边去,让后面的人跟进……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>

相关文章

  • 动态添加删除表格行的js实现代码

    动态添加删除表格行的js实现代码

    本篇文章主要是对动态添加删除表格行的js实现代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-02-02
  • javascript实现数字时钟效果

    javascript实现数字时钟效果

    这篇文章主要为大家详细介绍了javascript实现数字时钟效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • Javascript前端UI框架Kit使用指南之kitjs事件管理

    Javascript前端UI框架Kit使用指南之kitjs事件管理

    本文详细介绍了Kitjs的事件管理功能,包括普通的Dom事件、Kit如何解决问题、代码解析、注销事件等。需要的朋友可以参考下。
    2014-11-11
  • 详解Layer弹出层样式

    详解Layer弹出层样式

    学习layer弹出框,之前项目是用bootstrap模态框,后来改用layer弹出框,在文章的后面,我会分享项目的一些代码,需要的朋友可以参考下
    2017-08-08
  • 微信公众号H5之微信分享常见错误和问题(小结)

    微信公众号H5之微信分享常见错误和问题(小结)

    这篇文章主要介绍了微信公众号H5之微信分享常见错误和问题(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 详解操作cookie的原生方法cookieStore

    详解操作cookie的原生方法cookieStore

    我们平时对 cookie 的增删改查等操作,都是在操作document.cookie,这里我们介绍一个新方法cookieStore。
    2021-05-05
  • 基于javascript制作微信聊天面板

    基于javascript制作微信聊天面板

    这篇文章主要为大家详细介绍了基于javascript制作微信聊天面板的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 一款js和css代码压缩工具[附JAVA环境配置方法]

    一款js和css代码压缩工具[附JAVA环境配置方法]

    压缩css和js是我们工作中经常要处理的一件事,这里介绍的是一款基于YUICompressor,淘宝封装的css和js压缩工具TBCompressor.
    2010-04-04
  • Webpack常见使用配置小结

    Webpack常见使用配置小结

    本文主要介绍了Webpack常见使用配置小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • mockjs,json-server一起搭建前端通用的数据模拟框架教程

    mockjs,json-server一起搭建前端通用的数据模拟框架教程

    下面小编就为大家分享一篇mockjs,json-server一起搭建前端通用的数据模拟框架教程,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12

最新评论