文章目錄
- setTimeout (slow, takes about 10 sec)
- img.onerror (data:uri)
- script.onreadystatechange
- script.onload (data:uri)
- xhr.onreadystatechange (data:text/plain,foo)
- self.postMessage
就好像排隊,前面的人忙著忙著突然上廁所了,後面的人阻塞在這裡,因此我們就需要讓前面的人死到一邊去,讓後面的人跟進……AJAX就是這個概念,請求還在繼續,但我們還可以做其他事。
javascript中實現這個功能的是來自BOM的一個函數setTimeout,但相關的DOM操作也提供了一系列實現。如XMLHttpRequest對象與script標籤的onreadystatechange回調,image的onload與onerror回調,iframe的onload,DOM元素的事件回調,HTML5的跨域訊息傳送postMessage,QuickTime與flash對象的載入……
setTimeout的零秒延遲在前些年時間被國內宣揚得特別厲害,但setTimeout是所有延遲中最慢的,最少要花上10多毫秒,如果用setTimeout來開發特效,這特效會運行得比較慢。下面是一個效能測試: lang="en">
setTimeout (slow, takes about 10 sec)
function async(callback) { setTimeout(callback, 0); }
img.onerror (data:uri)
function async(callback) { var img = new Image; img.addEventListener('error', callback, false); img.src = 'data:,foo'; }
script.onreadystatechange
function async(callback) { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "javascript:"; script.onreadystatechange = function () { document.body.removeChild(script); callback(); } document.body.appendChild(script); }
script.onload (data:uri)
function async(callback) { var script = document.createElement('script'); script.onload = function() { document.body.removeChild(script); callback(); } script.src = 'data:text/javascript,'; document.body.appendChild(script); }
xhr.onreadystatechange (data:text/plain,foo)
function async(callback) { var xhr = new XMLHttpRequest; xhr.open('GET','data:text/plain,foo',true); xhr.onreadystatechange = function() { xhr.onreadystatechange = null; callback(); }; xhr.send(null); }
self.postMessage
function async(callback) { var n = ++async.count; window.addEventListener('message',function(e){ if (e.data == n) { window.removeEventListener('message', arguments.callee,false); callback(); } },false); window.postMessage(n, location.protocol + "//" + location.host); } async.count = 0;