麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > HTML > 正文

HTML5之多線程(Web Worker)

2024-08-26 00:21:15
字體:
來源:轉載
供稿:網友

提到 HTML5 總是讓人津津樂道,太多的特性和有趣的 API 讓人耳目一新。但是很多童鞋還停留在語義化的階段,忽視了 HTML5 的強勁之處。

這節我們來探討一下多線程 Web-Worker。

一、明確 JavaScript 是單線程

JavaScript 語言的一大特點就是單線程,也就是說,同一個時間只能做一件事。

聽起來有些匪夷所思,為什么不設計成多線程提高效率呢?我們可以假設一種場景:

假定 JavaScript 同時有兩個線程,一個線程在某個 DOM 節點上添加內容,另一個線程刪除了這個節點,這時瀏覽器應該以哪個線程為準?

作為瀏覽器腳本語言, JavaScript 的主要用途是與用戶互動,以及操作 DOM 。

這決定了它只能是單線程,否則會帶來很復雜的同步問題。為了避免復雜性,從一誕生, JavaScript 就是單線程,這已經成了這門語言的核心特征,估計短期內很難改變。

二、新曙光:Web Worker

單線程始終是一個痛點,為了利用多核 CPU 的計算能力, HTML5 提出 Web Worker 標準,允許 JavaScript 腳本創建多個線程。但是子線程完全受主線程控制,且不得操作 DOM 。

所以,這個新標準并沒有改變 JavaScript 單線程的本質。

Web Workers 是現代瀏覽器提供的一個 JavaScript 多線程解決方案,我們可以找到很多使用場景:

1.我們可以用 Web Worker 做一些大計算量的操作;

2.可以實現輪詢,改變某些狀態;

3.頁頭消息狀態更新,比如頁頭的消息個數通知;

4.高頻用戶交互,拼寫檢查,譬如:根據用戶的輸入習慣、歷史記錄以及緩存等信息來協助用戶完成輸入的糾錯、校正功能等

5.加密:加密有時候會非常地耗時,特別是如果當你需要經常加密很多數據的時候(比如,發往服務器前加密數據)。

6.預取數據:為了優化網站或者網絡應用及提升數據加載時間,你可以使用 Workers

來提前加載部分數據以備不時之需。

加密是一個使用 Web Worker 的絕佳場景,因為它并不需要訪問 DOM 或者利用其它魔法,它只是純粹使用算法進行計算而已。隨著大眾對個人敏感數據的日益重視,信息安全和加密也成為重中之重。這可以從近期的 12306 用戶數據泄露事件中體現出來。

一旦在 Worker 進行計算,它對于用戶來說是無縫地且不會影響到用戶體驗。

三、兼容性

HTML5,多線程

四、基本概念

1.首先記得去判斷是否支持

if (window.Worker) {  ...}

2.創建一個新的 worker 很簡單

const myWorker = new Worker('worker.js');

postMessage() 方法和 onmessage 事件處理函數是 Workers 的黑魔法。

3. postMessage 用來發送消息,而 onmessage 用來監聽消息

const worker = new Worker('src/worker.js');worker.onmessage = e => {  console.log(e.data);};worker.postMessage('你好嗎!');

在主線程中使用時, onmessage 和 postMessage() 必須掛在 worker 對象上,而在 worker 中使用時不用這樣做。原因是,在 worker 內部, worker 是有效的全局作用域。

4.異常處理:

worker.onerror = function(error) {  console.log(error.message);  throw error;};

5.終止 worker

worker.terminate();

worker 線程會被立即殺死,不會有任何機會讓它完成自己的操作或清理工作。

6.在 worker 線程中, workers 也可以調用自己的 close 方法進行關閉:

close();

五、快速開始

為了快速掌握,我們來做一個小例子:項目結構如下

├── index.html└── src    ├── main.js    └── worker.js

Html

<html><head>  <title>Web Work Demo</title>  <meta charset="UTF-8" /></head><body>  <div id="app"> Hello Jartto! </div>  <script src="src/main.js"></script></body></html>

main.js

const worker = new Worker('src/worker.js');worker.onmessage = e => {  const message = e.data;  console.log(`[From Worker]: ${message}`);  document.getElementById('app').innerHTML = message;};worker.postMessage('寫的真好!');

Work.js

onmessage = e => {  const message = e.data;  console.log(`[From Main]: ${message}`);  if(message.indexOf('好') > -1) {    postMessage('謝謝支持');  }};

代碼很簡單,主線程發送:「寫的真好!」

web worker 收到消息,發現內容中含有「好」字,回傳給主線程:「謝謝支持」

六、局限性

1.在 worker 內,不能直接操作 DOM 節點,也不能使用 window 對象的默認方法和屬性。然而我們可以使用大量 window 對象之下的東西,包括 WebSockets , IndexedDB 以及 FireFox OS 專用的 Data Store API 等數據存儲機制。

這里舉個例子,我們修改 main.js :

const worker = new Worker('src/worker.js');worker.onmessage = e => {  const message = e.data;  console.log(`[From Worker]: ${message}`);  document.getElementById('app').innerHTML = message;};+ worker.onerror = function(error) {+   console.log(error);+   worker.terminate();+ };worker.postMessage('寫的真好!');

再來修改 work.js

+ alert('jartto');onmessage = e => {  const message = e.data;  console.log(`[From Main]: ${message}`);  if(message.indexOf('好') > -1) {    postMessage('謝謝支持');  }};

這時候運行就會報出:

HTML5,多線程

這是因為: worker.js 執行的上下文,與主頁面 HTML 執行時的上下文并不相同,最頂層的對象并不是 Window, woker.js 執行的全局上下文,而是 WorkerGlobalScope ,我們具體說明。

2. workers 和主線程間的數據傳遞通過這樣的消息機制進行:雙方都使用 postMessage() 方法發送各自的消息,使用 onmessage 事件處理函數來響應消息(消息被包含在 Message 事件的 data 屬性中)。

這個過程中數據并不是被共享而是被復制。

3.同源限制

分配給 Worker 線程運行的腳本文件,必須與主線程的腳本文件同源。

4.文件限制

Worker 線程無法讀取本地文件,即不能打開本機的文件系統 (file://) ,它所加載的腳本,必須來自服務器。

5.不允許本地文件

Uncaught SecurityError: Failed to create a worker: 
script at '(path)/worker.js' 
cannot be accessed from origin 'null'.

Chrome doesn’t let you load web workers when running scripts from a local file.

那如何解決呢?我們可以啟動一個本地服務器,建議使用 http-server ,簡單易用。

6.內容安全策略

有別于創建它的 document 對象, worker 有它自己的執行上下文。因此普遍來說, worker 并不受限于創建它的 document (或者父級 worker )的內容安全策略。

我們來舉個例子,假設一個 document 有如下頭部聲明:

Content-Security-Policy: script-src 'self'

這個聲明有一部分作用在于,禁止它內部包含的腳本代碼使用 eval() 方法。然而,如果腳本代碼創建了一個 worker ,在 worker 上下文中執行的代碼卻是可以使用 eval() 的。

為了給 worker 指定 CSP,必須為發送 worker 代碼的請求本身加上一個 CSP。

有一個例外情況,即 worker 腳本的源如果是一個全局性的唯一的標識符(例如,它的 URL 指定了數據模式或者 blob ), worker 則會繼承創建它的 document 或者 worker 的 CSP 。

七、擴展:WorkerGlobalScope

關于 ,我們可以在 MDN 上面找到文檔:

1. self :

我們可以使用 WorkerGlobalScope 的 self 屬性來獲取這個對象本身的引用。

2. location :

location 屬性返回當線程被創建出來的時候與之關聯的 WorkerLocation 對象,它表示用于初始化這個工作線程的腳步資源的絕對 URL ,即使頁面被多次重定向后,這個 URL 資源位置也不會改變。

3. close :

關閉當前線程,與 terminate 作用類似。

4. caches :

當前上下文得 CacheStorage ,確保離線可用,同時可以自定義請求的響應。

5. console :

支持 console 語法。

6. importScripts 
我們可以通過 importScripts() 方法通過 url 在 worker 中加載庫函數。

7. XMLHttpRequest 
有了它,才能發出 Ajax 請求。

8.可以使用:

  • setTimeout/setInterval
  • addEventListener/postMessage

還有很多 API 可以使用,這里就不一一舉例了。

八、異常處理

當 worker 出現運行中錯誤時,它的 onerror 事件處理函數會被調用。它會收到一個擴展了 ErrorEvent 接口的名為 error 的事件。該事件不會冒泡并且可以被取消。

為了防止觸發默認動作,worker 可以調用錯誤事件的 preventDefault() 方法。

錯誤事件我們常用如下這三個關鍵信息:

  • Message:可讀性良好的錯誤消息;
  • Filename:發生錯誤的腳本文件名;
  • Lineno:發生錯誤時所在腳本文件的行號;
worker.onerror = function(error) {  console.log(error.message);  throw error;};

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到HTML教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久精品片 | a在线视频 | 久久综合精品视频 | 色婷婷久久久久久 | 欧美日韩一区,二区,三区,久久精品 | 亚洲影院在线播放 | 香蕉成人在线视频 | 日本黄色大片免费 | a集毛片 | 91精品国产乱码久久久久久久久 | 日韩视频精品一区 | 成人在线a | 成人在线视频免费播放 | 亚洲极色 | 中文字幕国产欧美 | 亚洲国产高清一区 | 亚洲最新色 | 男人天堂新地址 | 国产精品视频一区二区三区四 | 黄色大片免费网站 | 日韩精品久久久久久久九岛 | 91精品国产777在线观看 | 欧美视频在线观看一区 | 免费一级毛片电影 | 美国av免费看 | 欧美在线观看黄色 | www.91在线观看 | 91久久久久久亚洲精品禁果 | 91av大片 | 久久久久久麻豆 | 久久久精品视频免费看 | 亚洲午夜国产 | 激情视频免费看 | 成人不卡一区二区 | 欧美日本一 | 亚洲精华液久久含羞草 | 久久亚洲精品11p | 一区二区三区欧美在线 | 色网在线视频 | 美国一级黄色毛片 | 欧美大荫蒂xxx |