HTML5 Web Worker
Web Workers 是 HTML5 提供的一個javascript多線程解決方案,我們可以將一些大計算量的代碼交由web Worker運行而不凍結(jié)用戶界面。
WebWorker 可以做什么
- 可以加載一個JS進行大量的復雜計算而不掛起主進程,并通過
postMessage,onmessage進行通信 - 可以在
worker中通過importScripts(url)加載另外的腳本文件 - 可以使用
setTimeout(),clearTimeout(),setInterval(), andclearInterval() - 可以使用
XMLHttpRequest來發(fā)送請求 - 可以訪問
navigator的部分屬性 -
close()結(jié)束線程 -
navigator對象- 可以使用
localStorage和sessionStorage -
XMLHttpRequest可以在線程中使用Ajax
- 可以使用
- 預先抓取和/或緩存數(shù)據(jù)以便稍后使用
- 突出顯示代碼語法或其他實時文本格式
- 拼寫檢查程序
- 分析視頻或音頻數(shù)據(jù)
- 背景
I/O或網(wǎng)絡服務輪詢 - 處理較大數(shù)組或超大
JSON響應 -
<canvas>中的圖片過濾 - 更新本地網(wǎng)絡數(shù)據(jù)庫中的多行內(nèi)容
局限性
- 不能跨域加載J
S -
worker內(nèi)代碼不能訪問DOM - 各個瀏覽器對
Worker的實現(xiàn)不大一致,例如FF里允許worker中創(chuàng)建新的worker,而Chrome中不行 - 不是每個瀏覽器都支持這個新特性
WebWorker 使用
-
Worker創(chuàng)建
var worker = new Worker('task.js') -
Worker啟動
worker.postMessage() -
Worker事件
worker.addEventListener('message'/'error', function(e) {e.data;}, false);
加載外部腳本
importScripts('script1.js');
importScripts('script2.js');
// 或
importScripts('script1.js', 'script2.js');
子Worker (參考鏈接)
- 子
Worker必須托管在與父網(wǎng)頁相同的來源中。 - 子
Worker中的 URI 應相對于父Worker的位置進行解析(與主網(wǎng)頁不同)。 - 在主網(wǎng)頁和
Worker之間傳遞的消息是復制而不是共享的。
內(nèi)嵌Worker
即時創(chuàng)建 Worker 腳本,或者在不創(chuàng)建單獨 Worker 文件的情況下創(chuàng)建獨立網(wǎng)頁
// Prefixed in Webkit, Chrome 12, and FF6: window.WebKitBlobBuilder, window.MozBlobBuilder
var bb = new BlobBuilder();
bb.append("onmessage = function(e) { postMessage('msg from worker'); }");
// Obtain a blob URL reference to our worker 'file'.
// Note: window.webkitURL.createObjectURL() in Chrome 10+.
var blobURL = window.URL.createObjectURL(bb.getBlob());
var worker = new Worker(blobURL);
worker.onmessage = function(e) {
// e.data == 'msg from worker'
};
worker.postMessage(); // Start the worker.
Blob 網(wǎng)址
對window.URL.createObjectURL() 的調(diào)用十分奇妙。此方法創(chuàng)建了一個簡單的網(wǎng)址字符串,該字符串可用于 DOM File 或 Blob 對象中存儲的參考數(shù)據(jù)。例如:blob:http://localhost/c745ef73-ece9-46da-8f66-ebes574789b1
Blob 網(wǎng)址是唯一的,且只要應用存在,該網(wǎng)址就會一直有效(例如直到卸載 document 為止)。如果您要創(chuàng)建很多 Blob 網(wǎng)址,最好發(fā)布不再需要的參考資料。您可以通過將 Blob 網(wǎng)址傳遞給 window.URL.revokeObjectURL() 來明確發(fā)布該網(wǎng)址:
window.URL.revokeObjectURL(blobURL); // window.webkitURL.createObjectURL() in Chrome 10+.
使用 WebWorker 技巧
示例只涉及 XMLHttpRequest 和計算;不是很大也不復雜。如果您讓 worker 處理更復雜的任務,比如處理大量計算,它將會是一個功能強大的特性。在將這個很酷的技術運用到您的項目之前,了解一些使用技巧。
- 在
workers中不能訪問DOM(非線程安全)windowdocumentparent -
為了安全,
workers不能直接對 HTML 進行操作。同一DOM上的多線程操作可能會引發(fā)線程安全問題。優(yōu)勢是您不再擔憂worker實現(xiàn)中的多線程安全問題。
這在開發(fā)worker時有一些局限性,您不能在worker中調(diào)用alert(),這是一個非常流行的調(diào)試 JavaScript 代碼的方法。您也不能調(diào)用document.getElementById(),因為它只能檢索和返回變量(可能是字符串、數(shù)組、JSON 對象,等等)。 -
worker中可用的對象 - 盡管
worker不能訪問 window 對象,但可以直接訪問navigator。您也可以在navigator對象中訪問appNameappVersionplatform和userAgent。 -
location對象可以以 只讀方式訪問。您可以在location對象中獲取hostname和port。
在worker中也支持XMLHttpRequest。有了這一特性,您就可以將大量感興趣的擴展添加到worker中。
此外還有:
-
importScripts()方法(導入外部腳本文件, 在同一個域上訪問) -
JavaScript對象,比如ObjectArrayDateMath和String -
setTimeout()clearTimeout()和setInterval()clearInterval()方法 - 應用緩存
- 生成其他
Web Worker -
postMessage中攜帶的數(shù)據(jù)類型-
postMessage的使用十分頻繁,因為它是主JavaScript線程的主要方法,用于和workers 交互。然而,現(xiàn)在postMessage中攜帶的數(shù)據(jù)類型僅限于本地JavaScript類型,比如,ArrayDateMathStringJSON等等。結(jié)構(gòu)復雜的自定義JavaScript對象不能被很好地支持。
-
WebWorker 安全
postMessage在HTML5中被引入,用來解決跨域或者跨線程數(shù)據(jù)交互的問題。但是如果messaging可以接收任何來源的信息,此頁面有可能會被攻擊;另外postMessage不通過服務器,如果不經(jīng)過驗證和過濾,可能成為XSS注入點。
- 使用
postMessage時需要驗證來源可信; - 不要使用
innerHTML,現(xiàn)代瀏覽器提供了textContent屬性,可以幫助對HTML標簽進行過濾,或者你可以自行編寫過濾的邏輯和函數(shù)。