HTML5 之 Web Worker

HTML5 Web Worker

Web WorkersHTML5 提供的一個javascript多線程解決方案,我們可以將一些大計算量的代碼交由web Worker運行而不凍結(jié)用戶界面。

WebWorker 可以做什么

  • 可以加載一個JS進行大量的復雜計算而不掛起主進程,并通過postMessage,onmessage進行通信
  • 可以在worker中通過importScripts(url)加載另外的腳本文件
  • 可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()
  • 可以使用XMLHttpRequest來發(fā)送請求
  • 可以訪問navigator的部分屬性
  • close()結(jié)束線程
  • navigator對象
    • 可以使用localStoragesessionStorage
    • XMLHttpRequest可以在線程中使用Ajax
  • 預先抓取和/或緩存數(shù)據(jù)以便稍后使用
  • 突出顯示代碼語法或其他實時文本格式
  • 拼寫檢查程序
  • 分析視頻或音頻數(shù)據(jù)
  • 背景 I/O 或網(wǎng)絡服務輪詢
  • 處理較大數(shù)組或超大 JSON 響應
  • <canvas>中的圖片過濾
  • 更新本地網(wǎng)絡數(shù)據(jù)庫中的多行內(nèi)容

局限性

  • 不能跨域加載JS
  • 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 FileBlob 對象中存儲的參考數(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(非線程安全) window document parent
  • 為了安全,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 對象中訪問 appName appVersion platformuserAgent
  • location 對象可以以 只讀方式訪問。您可以在 location 對象中獲取 hostnameport。
    worker 中也支持 XMLHttpRequest。有了這一特性,您就可以將大量感興趣的擴展添加到 worker 中。

此外還有:

  • importScripts() 方法(導入外部腳本文件, 在同一個域上訪問)
  • JavaScript 對象,比如 Object Array Date MathString
  • setTimeout() clearTimeout()setInterval() clearInterval()方法
  • 應用緩存
  • 生成其他Web Worker
  • postMessage 中攜帶的數(shù)據(jù)類型
    • postMessage 的使用十分頻繁,因為它是主 JavaScript 線程的主要方法,用于和 workers 交互。然而,現(xiàn)在 postMessage 中攜帶的數(shù)據(jù)類型僅限于本地 JavaScript 類型,比如,Array Date Math String JSON 等等。結(jié)構(gòu)復雜的自定義 JavaScript 對象不能被很好地支持。

WebWorker 安全

postMessageHTML5中被引入,用來解決跨域或者跨線程數(shù)據(jù)交互的問題。但是如果messaging可以接收任何來源的信息,此頁面有可能會被攻擊;另外postMessage不通過服務器,如果不經(jīng)過驗證和過濾,可能成為XSS注入點。

  • 使用postMessage時需要驗證來源可信;
  • 不要使用innerHTML,現(xiàn)代瀏覽器提供了textContent屬性,可以幫助對HTML標簽進行過濾,或者你可以自行編寫過濾的邏輯和函數(shù)。

參考

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容