日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JavaScriptWebWorkers的構(gòu)建塊及5個使用場景是什么-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

10年積累的成都網(wǎng)站設計、網(wǎng)站制作經(jīng)驗,可以快速應對客戶對網(wǎng)站的新想法和需求。提供各種問題對應的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡服務。我雖然不認識你,你也不認識我。但先網(wǎng)站設計后付款的網(wǎng)站建設流程,更有左云免費網(wǎng)站建設讓你可以放心的選擇與我們合作。

這次我們會逐步講解Web Workers,先說個簡單的概念,接著討論不同類型的Web Workers,他們的組成部分是如何一起工作的,以及不同場景下它們各自優(yōu)勢和限制。最后,提供5個正確使用Web Workers 的場景。

正如我們前面文章討論的那樣,你應該知道 JavaScript 語言采用的是單線程模型。然而,JavaScript 也為開發(fā)人員提供了編寫異步代碼的機會。

異步編程的局限性

以前的文章討論過異步編程,以及應該在什么時候使用它。

異步編程可以讓UI界面是響應式(渲染速度快)的,通過"代碼調(diào)度",讓需要請求時間的代碼先放到在 event loop中晚一點再執(zhí)行,這樣就允許UI先行渲染展示。

異步編程的一個很好的用例就AJAX 請求。由于請求可能花費大量時間,因此可以使用異步請求,在客戶端等待響應的同時還可以執(zhí)行其他代碼。

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

然而,這帶來了一個問題——請求是由瀏覽器的WEB API處理的,但是如何使其他代碼是異步的呢?例如,如果成功回調(diào)中的代碼非常占用CPU:

var result = performCPUIntensiveCalculation();

如果performCPUIntensiveCalculation 不是一個HTTP請求而是一個阻塞代碼(比如一個內(nèi)容很多的for loop循環(huán)),就沒有辦法及時清空事件循環(huán),瀏覽器的UI 渲染就會被阻塞,頁面無法及時響應給用戶。

這意味著異步函數(shù)只能解決一小部分 JavaScript 語言單線程中的局限性問題。

在某些情況下,可以使用setTimeout 對長時間運行的計算阻塞的,可以使用setTimeout暫時放入異步隊列中,從讓頁面得到更快的渲染。例如,通過在單獨的setTimeout 調(diào)用中批處理復雜的計算,可以將它們放在事件循環(huán)中單獨的“位置”上,這樣可以爭取為 UI渲染/響應的執(zhí)行時間。

看一個簡單的函數(shù),計算一個數(shù)字數(shù)組的平均值:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

以下是重寫上述代碼并“模擬”異步性的方法:

function averageAsync(numbers, callback) {
    var len = numbers.length,
        sum = 0;

    if (len === 0) {
        return 0;
    } 

    function calculateSumAsync(i) {
        if (i < len) {
            // Put the next function call on the event loop.
            setTimeout(function() {
                sum += numbers[i];
                calculateSumAsync(i + 1);
            }, 0);
        } else {
            // The end of the array is reached so we're invoking the callback.
            callback(sum / len);
        }
    }

    calculateSumAsync(0);
}

使用setTimeout函數(shù),該函數(shù)將在事件循環(huán)中進一步添加計算的每個步驟。在每次計算之間,將有足夠的時間進行其他計算,從而可以讓瀏覽器進行渲染。

Web Worker 可以解決這個問題

HTML5為我們帶來了很多新的東西,包括:

  • SSE(我們在前一篇文章中已經(jīng)描述并與WebSockets進行了比較)
  • Geolocation
  • Application cache
  • Local Storage
  • Drag and Drop
  • Web Workers

Web Worker 概述

Web Worker 的作用,就是為 JavaScript 創(chuàng)造多線程環(huán)境,允許主線程創(chuàng)建 Worker 線程,將一些任務分配給后者運行。在主線程運行的同時,Worker 線程在后臺運行,兩者互不干擾。等到 Worker 線程完成計算任務,再把結(jié)果返回給主線程。這樣的好處是,一些計算密集型或高延遲的任務,被 Worker 線程負擔了,主線程(通常負責 UI 交互)就會很流暢,不會被阻塞或拖慢。

你可能會問:“JavaScript不是一個單線程的語言嗎?”

事實上 JavaScript 是一種不定義線程模型的語言。Web Workers 不是 JavaScript 的一部分,而是可以通過 JavaScript 訪問的瀏覽器特性。歷史上,大多數(shù)瀏覽器都是單線程的(當然,這已經(jīng)改變了),大多數(shù) JavaScript 實現(xiàn)都入發(fā)生在瀏覽器中。Web Workers 不是在 Node.JS 中實現(xiàn)的。Node.js 中有類似的集群(cluster)、子進程概念(child_process),他們也是多線程但是和 Web Workers 還是有區(qū)別 。

值得注意的是,規(guī)范 中提到了三種類型的 Web Workers:

  • 專用 Workers (Dedicated Workers)
  • 共享 Workers (Shared Workers)
  • 服務 Workers (Service workers)

Dedicated Workers

專用 Workers 只能被創(chuàng)建它的頁面訪問,并且只能與它通信。以下是瀏覽器支持的情況:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

Shared Workers

共享 Workers 在同一源(origin)下面的各種進程都可以訪問它,包括:iframes、瀏覽器中的不同tab頁(一個tab頁就是一個單獨的進程,所以Shared Workers可以用來實現(xiàn) tab 頁之間的交流)、以及其他的共享 Workers。以下是瀏覽器支持的情況:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

Service workers

Service Worker 功能:

  • 后臺消息傳遞
  • 網(wǎng)絡代理,轉(zhuǎn)發(fā)請求,偽造響應
  • 離線緩存
  • 消息推送

在目前階段,Service Worker 的主要能力集中在網(wǎng)絡代理和離線緩存上。具體的實現(xiàn)上,可以理解為 Service Worker 是一個能在網(wǎng)頁關閉時仍然運行的 Web Worker。以下是瀏覽器支持的情況:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

本文主要討論 專用 Workers,沒有特別聲明的話,Web Workers、Workers都是指代的專用 Workers。

Web Workers 是如何工作

Web Workers 一般通過腳本為.js 文件來構(gòu)建,在頁面中還通過了一些異步的 HTTP 請求,這些請求是完全被隱藏了的,你只需要調(diào)用 Web Worker API.

Worker 利用類線程間消息傳遞來實現(xiàn)并行性。它們保證界面的實時性、高性能和響應性呈現(xiàn)給用戶。

Web Workers 在瀏覽器中的一個獨立線程中運行。因此,它們執(zhí)行的代碼需要包含在一個單獨的文件中。這一點很重要,請記住!

讓我們看看基本 Workers 是如何創(chuàng)建的:

var worker = new Worker('task.js');

Worker() 構(gòu)造函數(shù)的參數(shù)是一個腳本文件,該文件就是 Worker 線程所要執(zhí)行的任務。由于 Worker 不能讀取本地文件,所以這個腳本必須來自網(wǎng)絡。如果下載沒有成功(比如404錯誤),Worker 就會默默地失敗。

為了啟動創(chuàng)建的 Worker,需要調(diào)用postMessage 方法:

worker.postMessage();

Web Worker 通信

為了在 Web Worker 和創(chuàng)建它的頁面之間進行通信,需要使用postMessage 方法或 Broadcast Channel。

postMessage 方法

新瀏覽器支持JSON對象作為方法的第一個參數(shù),而舊瀏覽器只支持字符串。

來看一個示例,通過將 JSON 對象作為一個更“復雜”的示例傳遞,創(chuàng)建 Worker 的頁面如何與之通信。傳遞字符串跟傳遞對象的方式也是一樣的。

讓我們來看看下面的 HTML 頁面(或者更準確地說是它的一部分):



然后這是 worker 中的 js 代碼:

self.addEventListener('message', function(e) {
  var data = e.data;
  switch (data.cmd) {
    case 'average':
      var result = calculateAverage(data); // 從數(shù)值數(shù)組中計算平均值的函數(shù)
      self.postMessage(result);
      break;
    default:
      self.postMessage('Unknown command');
  }
}, false);

當單擊該按鈕時,將從主頁調(diào)用postMessage。postMessage 行將 JSON 對象傳給Worker。Worker 通過定義的消息處理程序監(jiān)聽并處理該消息。

當消息到達時,實際的計算在worker中執(zhí)行,而不會阻塞事件循環(huán)。Worker 檢查傳遞的事件參數(shù)e,像執(zhí)行 JavaScript 函數(shù)一樣,處理完成后,把結(jié)果傳回給主頁。

在 Worker 作用域中,this 和 self 都指向 Worker 的全局作用域。

有兩種方法可以停止 Worker:從主頁調(diào)用worker.terminate() 或在worker 內(nèi)部調(diào)用self.close()

Broadcast Channel

Broadcast Channel API 允許同一原始域和用戶代理下的所有窗口,iFrames 等進行交互。也就是說,如果用戶打開了同一個網(wǎng)站的的兩個標簽窗口,如果網(wǎng)站內(nèi)容發(fā)生了變化,那么兩個窗口會同時得到更新通知。

還是不明白?就拿 Facebook 作為例子吧,假如你現(xiàn)在已經(jīng)打開 了Facebook 的一個窗口,但是你此時還沒有登錄,此時你又打開另外一個窗口進行登錄,那么你就可以通知其他窗口/標簽頁去告訴它們一個用戶已經(jīng)登錄了并請求它們進行相應的頁面更新。

// Connection to a broadcast channel
var bc = new BroadcastChannel('test_channel');

// Example of sending of a simple message
bc.postMessage('This is a test message.');

// Example of a simple event handler that only
// logs the message to the console
bc.onmessage = function (e) { 
  console.log(e.data); 
}

// Disconnect the channel
bc.close()

可以從下面這張圖,在視覺上來清晰地感受 Broadcast Channel:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

Broadcast Channel 瀏覽器支持比較有限:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

消息的大小

有兩種方式發(fā)送消息給Web Workers:

  • 復制消息:消息被序列化、復制、發(fā)送,然后在另一端反序列化。頁面和 Worker 不共享相同的實例,因此最終的結(jié)果是每次傳遞都會創(chuàng)建一個副本大多數(shù)瀏覽器,在兩邊都是使用的JSON對值進行編碼和解碼,這樣對數(shù)據(jù)的解碼、編碼操作,勢必會增加消息傳輸過程的時間開銷。信息越大,發(fā)送的時間就越長。
  • 傳遞消息:這意味著原始發(fā)送方在一旦發(fā)送后不能再使用它。傳輸數(shù)據(jù)幾乎是瞬間的,這種傳輸方式的局限性在于只能用 ArrayBuffer 類型來傳遞。

Web Workers 可用的特性

由于 JavaScript的多線程特性,Web工作者只能訪問JavaScript特性的一個子集。以下是它的一些特點:

Web Workers 由于具有多線程特性,因此只能訪問 JavaScript 特性的子集。 以下是可使用特性列表:

  • navigator 對象
  • location 對象(只讀)
  • MLHttpRequest
  • setTimeout()/clearTimeout() and setInterval()/clearInterval()
  • 應用緩存(Application Cache)
  • 使用importScripts() 導入外部腳本
  • 創(chuàng)建其他的 Web Workers

Web Workers 的局限性

遺憾的是,Web Workers 無法訪問一些非常關鍵的 JavaScript 特性:

  • DOM(它會造成線程不安全)
  • window 對象
  • document  對象
  • parent 對象

這意味著 Web Worker 不能操作 DOM (因此也不能操作 UI)。有時這可能很棘手,但是一旦你了解了如何正確使用 Web Workers,你就會開始將它們作為單獨的“計算機”使用,而所有 UI 更改都將發(fā)生在你的頁面代碼中。 Workers 將為你完成所有繁重的工作,然后一旦完成再把結(jié)果返回給 page 頁面。

處理錯誤

和 JavaScript 代碼一樣,Web workers 里拋出的錯誤,你也需要進行處理。當 Worker 執(zhí)行過程中如果遇到錯誤,會觸發(fā)一個ErrorEvent 事件。接口包含了三個有用的屬性來幫忙排查問題:

  • filename  -  導致 Worker 的腳本名稱
  • lineno - 發(fā)生錯誤的行號
  • message - 對錯誤的描述

例子如下:

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

在這里,可以看到我們創(chuàng)建了一個 worker 并開始偵聽錯誤事件。

JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么

在 worker 內(nèi)部(在workerWithError.js 中),我們通過將未定義x 乘以 2 來創(chuàng)建一個異常。異常被傳播到初始腳本,然后通過頁面監(jiān)聽 error事件,對錯誤進行捕獲。

5個好的 Web Workers 應用實例

到目前為止,我們已經(jīng)列出了 Web Workers 的優(yōu)點和局限性?,F(xiàn)在讓我們看看它們最強大的用例是什么:

  • Ray tracing(光線追蹤):光線追蹤是一種以像素為單位跟蹤光的路徑生成圖像的渲染技術。光線追蹤利用 CPU 密集型的數(shù)學計算來模擬光的路徑。其思想是模擬一些效果,如反射、折射、材料等。所有這些計算邏輯都可以添加到 Web Worker 中,以避免阻塞 UI線程。更好的是——可以很容易地在多個 workers 之間(以及在多個cpu之間)分割圖像呈現(xiàn)。下面是一個使用 Web Workers 的光線追蹤的簡單演示—https://nerget.com/rayjs-mt/r...。
  • Encryption(加密):由于對個人和敏感數(shù)據(jù)的監(jiān)管越來越嚴格,端到端加密越來越受歡迎。加密是一件非常耗時的事情,特別是如果有很多數(shù)據(jù)需要頻繁加密(例如,在發(fā)送到服務器之前)。這是一個使用 Web Worker 非常好的場景,因為它不需要訪問 DOM 或任何花哨的東西——它是完成其工作的純算法。只要是在 Web Worker 中工作的,對于端用戶就是無縫的,不會影響到體驗。
  • Prefetching data(預取數(shù)據(jù)):為了優(yōu)化你的網(wǎng)站或 web 應用程序并改進數(shù)據(jù)加載時間,你可以利用 Web Workers 提前加載和存儲一些數(shù)據(jù),以便在需要時稍后使用。Web Workers 在這種情況下非常棒,因為它們不會影響應用程序的UI,這與不使用Workers 時是不同的。
  • Progressive Web Apps(漸進式Web應用程序):這種漸進式Web應用程序要求,即使在用戶網(wǎng)絡不穩(wěn)定的條件下,也能夠迅速的加載。這意味著數(shù)據(jù)必須本地存儲在瀏覽器中。這也是 IndexDB 或類似 api 發(fā)揮作用的地方。通常情況下,客戶端的存儲都是必要的,但使用起來需要不阻塞UI渲染線程,那么工作就需要在 Worker 中進行了。不過,以IndexDB 為例,它提供了一些異步的API,調(diào)用它們的話也不需要使用 web worker,但如果是同步的 API,就必須要在 Worker 中使用了。
  • Spell checking(拼寫檢查):一個基本的拼寫檢查程序的工作流程如下-程序讀取一個字典文件與一個正確拼寫單詞列表。字典被解析為一個搜索樹,以使實際的文本搜索更有效。當一個單詞被提供給檢查器時,程序檢查它是否存在于預先構(gòu)建的搜索樹中。如果在樹中沒有找到該單詞,可以通過替換替換字符并測試它是否是有效的單詞(如果是用戶想要寫的單詞),為用戶提供替代拼寫。所有的這些處理過程都可以在 Web Worker中進行了,用戶可以不被阻塞的輸入詞匯和句子,Web Worker 在后臺校驗詞匯是否正確以及提供備選詞匯。

感謝各位的閱讀!關于JavaScript Web Workers的構(gòu)建塊及5個使用場景是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!


當前標題:JavaScriptWebWorkers的構(gòu)建塊及5個使用場景是什么-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://www.dlmjj.cn/article/esdgg.html