javascript異步編程
javascript中實(shí)現(xiàn)這個(gè)功能的是來自BOM的一個(gè)函數(shù)setTimeout,但相關(guān)的DOM操作也提供了一系列實(shí)現(xiàn)。如XMLHttpRequest對(duì)象與script標(biāo)簽的onreadystatechange回調(diào),image的onload與onerror回調(diào),iframe的onload,DOM元素的事件回調(diào),HTML5的跨域消息傳送postMessage,QuickTime與flash對(duì)象的加載……
setTimeout的零秒延遲在前些年時(shí)間被國(guó)內(nèi)宣揚(yáng)得特別厲害,但setTimeout是所有延遲中最慢的,最少要花上10多毫秒,如果用setTimeout來開發(fā)特效,這特效會(huì)運(yùn)行得比較慢。下面是一個(gè)性能測(cè)試:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
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 |
為了處理這種異步調(diào)用,Mochikit從Python的Twisted框架借來了Deferred這個(gè)類,并用它來處理AJAX的回調(diào)。AJAX的回調(diào)通常有兩種,成功加載時(shí)的回調(diào)與請(qǐng)求失敗的回調(diào),IE8的XDomainRequest就有這兩種回調(diào)了,標(biāo)準(zhǔn)瀏覽器的script與image也有這兩種回調(diào),分別稱之為onload與onerror。Mochikit的Deferred實(shí)例就內(nèi)置一個(gè)數(shù)組,每次包含這兩種回調(diào),依次執(zhí)行。Mochikit這偉大的遺產(chǎn)后來由dojo發(fā)揚(yáng)光大了,至于怎么用,自己google吧。
下面是我的框架對(duì)它的應(yīng)用,我已把它整合到我的框架中:
<!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>
后臺(tái):
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
在日本一博客提到這樣一個(gè)捕捉異步錯(cuò)誤的例子:
function throwError(){
throw new Error('ERROR');
}
try{
setTimeout(throwError, 3000);
} catch(e){
alert(e);
}
看來try...catch是無法捕捉這種形式的錯(cuò)誤,window.onerror可以,但好像只有IE與FF支持。如果用Deferred來處理,就簡(jiǎn)單了!
dom.Deferred.next(function () {
throw new Error("錯(cuò)誤")
}).wait(1).error(function(e){
alert(e instanceof Error)
});
列隊(duì)處理。由于是使用了異步,因此不會(huì)阻塞頁(yè)面的演染。
<!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/>"
});
});
/*結(jié)果
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>
相關(guān)文章
CKEditor擴(kuò)展插件:自動(dòng)排版功能autoformat插件實(shí)現(xiàn)方法詳解
這篇文章主要介紹了CKEditor擴(kuò)展插件:自動(dòng)排版功能autoformat插件實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了CKEditor擴(kuò)展插件實(shí)現(xiàn)自動(dòng)排版功能的autoformat插件具體定義、配置與使用技巧,需要的朋友可以參考下2020-02-02json數(shù)據(jù)與字符串的相互轉(zhuǎn)化示例
json與字符串之間的轉(zhuǎn)換,在使用中經(jīng)常會(huì)遇到,本文有個(gè)不錯(cuò)的示例,大家可以參考下,或許會(huì)有所幫助2013-09-09BootStrap Progressbar 實(shí)現(xiàn)大文件上傳的進(jìn)度條的實(shí)例代碼
這篇文章主要介紹了BootStrap Progressbar 實(shí)現(xiàn)大文件上傳的進(jìn)度條的實(shí)例代碼的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06bootstrap table動(dòng)態(tài)加載數(shù)據(jù)示例代碼
本篇文章主要介紹了bootstrap table動(dòng)態(tài)加載數(shù)據(jù)示例代碼,可以實(shí)現(xiàn)點(diǎn)擊選擇按鈕,彈出模態(tài)框,加載出關(guān)鍵詞列表,有興趣的可以了解一下。2017-03-03原生JS實(shí)現(xiàn)天氣預(yù)報(bào)
這篇文章主要為大家詳細(xì)介紹了原生JS實(shí)現(xiàn)天氣預(yù)報(bào),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06bootstrap-table獲取表格數(shù)據(jù)的多種方式
這篇文章主要介紹了bootstrap-table獲取表格數(shù)據(jù)的多種方式,bootstrap-table獲取值得兩種方式,一種是通過data獲取,一種是通過url獲取,需要的朋友可以參考下2023-10-10