JavaScript >> Javascript 文檔 >  >> Tags >> web

試驗網絡工作者

在過去的幾個月裡,有一些關於網絡工作者的好信息流傳開來。我不想再在博客圈中添加對該主題的介紹,但我想分享一些關於我與網絡工作者的經驗的信息。以下是我在使用 API 時的一些筆記。

工作者全局範圍

關於 worker 的有趣之處在於,它們有自己的全局範圍,與我們在 JavaScript 中我們都知道和害怕的全局範圍是分開的。 Worker 不共享頁面內 JavaScript 用於執行的瀏覽器 UI 線程,因此不允許訪問 DOM 或大部分 BOM。實際上,worker 是一個沙盒環境,其中 JavaScript 可以完全獨立於頁面運行。這就是為什麼工作代碼必須存在於單獨的文件中,而不是與頁面代碼位於同一位置的原因。典型的創作是這樣的:

var worker = new Worker("worker.js")

文件 worker.js 包含要在 worker 中執行的所有代碼。該代碼在工作人員的全局範圍內執行。 worker 的全局範圍包含一組有限的功能,包括:

  • XMLHttpRequest 構造函數。
  • 一個self 對象,它是代表此範圍內工作人員的全局對象。
  • 所有 ECMAScript 構造函數。
  • 一個navigator 僅包含 appName、appVersion、userAgent 和平台屬性的對象。
  • 一個location 除了所有屬性都是只讀的之外,與 window.location 相同的對象。
  • setTimeout()setInterval() .
  • 一個importScripts() 方法,用於將外部 JavaScript 文件加載到 worker 的作用域中。

與其他 ECMAScript 環境一樣,全局變量成為 self 上的屬性 .大多數工人的例子都顯示了一個非常糟糕的模式,它混淆了正在發生的事情:

//inside worker.js
onmessage = function(event){
    //do something in response to the event
};

我反複查看這段代碼,試圖弄清楚到底發生了什麼。為什麼要為函數分配全局變量?然後我發現 self 是對 worker 全局作用域的引用,因此我決定改寫如下代碼:

//inside worker.js
self.onmessage = function(event){
    //do something in response to the event
};

這個小添加使示例代碼更具可讀性,因為這種模式在 JavaScript 中很常見。我強烈建議任何使用 Web Worker 編寫代碼的人都遵守直接在 self 上分配屬性和調用方法的約定 反對以避免任何混淆。還值得一提的是 this 指向 self 在全局工作者範圍內訪問時。

工人消息傳遞

Worker 不能直接影響頁面中的更改,而是依靠消息傳遞系統來回傳遞數據。 postMessage() 方法用於在 Worker 上調用時將數據發送到工作人員 頁面中的實例,並在工作人員全局對像上調用時將數據發送出工作人員。示例:

//on page
var worker = new Worker("worker.js");

//receive message from the worker
worker.onmessage = function(event){
    alert(event.data);
};

//send message to the worker
worker.postMessage("Nicholas");

//in worker.js
//receive message from the page
self.onmessage = function(event){

    //send message back to the page
    this.postMessage("Hello, " + event.data);

};

通信雙方的API完全相同。調用 postMessage() 導致 message 在接收器上異步觸發的事件。必須使用設置 onmessage 的舊 DOM 0 樣式分配事件處理程序 等於一個函數。 event 對像有一個名為 data 的屬性 包含來自供應商的信息。

這個消息傳遞系統最有趣的地方可能是數據傳輸的方式。您可以傳遞任何原始數據類型(字符串、數字、布爾值、null , 或 undefined ) 以及 Object 的任何實例 或 Array 這不是 DOM 或 BOM 的一部分。棘手的部分是值似乎是直接傳遞的,例如:

//on page
var worker = new Worker("worker.js");

//receive message from the worker
worker.onmessage = function(event){
    alert(event.data.name);   //"Nicholas"
};

//send object to the worker
worker.postMessage({ name: "Nicholas" });

//in worker.js
//receive message from the page
self.onmessage = function(event){

    //send message back to the page
    var name = event.data.name;   //comes through fine!
    this.postMessage(event.data);

};

此代碼在頁面和 Web Worker 之間來回傳遞一個對象。你會注意到 name 財產在這兩個地方都可以訪問。這給出了對象直接傳遞給工作人員然後返回的外觀。實際上,這不可能發生,因為工作人員處於其自己的分離範圍內。實際發生的是值在通過時被序列化,然後在另一端被反序列化。頁面和工作人員不能共享對象實例,只能共享對像中表示的數據。 Firefox 實際上是通過對值進行 JSON 編碼,然後在另一端對其進行 JSON 解碼來實現這一點的。最終結果是創建了原始數據的副本。

更好的消息傳遞

乍一看,消息系統似乎有點過於簡單,只有 postMessage() 只接受一個參數通過。傳遞原始值似乎是一種糟糕的交流方式,因為沒有上下文。我現在一直都在傳遞對象,所以我可以提供更好的上下文來說明原因。示例:

//on page
var worker = new Worker("worker.js");

//send object to the worker
worker.postMessage({
    type: "first",
    data: "Nicholas"
});

//send object to the worker
worker.postMessage({
    type: "last",
    data: "Zakas"
});

//in worker.js
//receive message from the page
self.onmessage = function(event){

    //determine what to do
    switch(event.data.type){
        case "first":
            //do something
            break;
        case "last":
            //do something else
            break;
        //and so on...
    }
};

通過始終傳遞帶有一些上下文數據的對象,您的工作人員知道如何處理它收到的數據。

總結

Worker 似乎是瀏覽器中一個有趣的功能,最終可能會被證明是有用的。 Web 開發人員需要一段時間才能完全掌握可以在 worker 中完成的以數據為中心的 JavaScript 的概念,而以 DOM 為中心的 JavaScript 則不能。然而,在這一點上,我並不完全相信工作者在大多數 Web 應用程序中的用處。大多數漂浮在那裡的示例看起來很酷,但並不是 JavaScript 將或應該在 Web 應用程序中做的事情。我還沒有遇到過這樣的例子,我說過,“哦,伙計,如果只有網絡工作者得到廣泛支持,這將很容易,”所以我想知道那一天是否會到來,或者工作者是否會被降級到沒有實際應用的概念驗證領域。


Tutorial JavaScript 教程
  1. 在chartJS中跳過y軸上的小數點

  2. 搜索引擎和社交媒體爬蟲如何渲染 JavaScript

  3. JS——從base64代碼中獲取圖片的寬高

  4. 了解 Node.js:CTC

  5. 以正確的方式測試有狀態的 React 組件

  6. 歡迎 .NET 加入開源空間!

  7. Adobe 啟動編碼標準

  1. 檢查對像是否已定義,最佳實踐。

  2. 使用 Porter 在 AWS/GCP/Digital Ocean 上部署 Strapi

  3. 什麼返回false;做?

  4. 如何將 React 應用程序部署到 Netlify(第 1 部分)

  5. 使用 Express 和 PostgreSQL 的最小用戶管理

  6. Chrome Canvas 中的亞像素渲染

  7. 👨‍🔬 為什麼 DOM 會導致負焓! - 深入學習前端 - 第 2 部分

  1. 使用 Vue 和 D3.js 進行數據可視化簡介

  2. 使用 Node + Typescript + yarn 創建 devenv

  3. 為什麼我們一直在談論 CSS-in-JS?

  4. JavaScript 在索引處拆分字符串 |特定和第 n 個位置示例