日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

PWA(Progressive Web App)入门系列:(五)Web Worker

發(fā)布時(shí)間:2023/12/9 编程问答 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PWA(Progressive Web App)入门系列:(五)Web Worker 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在說(shuō)Service Worker前有必要說(shuō)一下Web Worker,因?yàn)镾ervice Worker本身就屬于Web Worker的延伸,大部分功能也是基于Web Worker進(jìn)行的擴(kuò)展。

背景

眾所周知,JavaScript引擎是以單線程調(diào)度的方式進(jìn)行,我們無(wú)法同時(shí)運(yùn)行多個(gè)JavaScript文件,這種情況下就會(huì)導(dǎo)致對(duì)硬件資源無(wú)法充分利用,并且當(dāng)在進(jìn)行一些高耗性能的操作時(shí),會(huì)影響主線程的其他任務(wù),造成任務(wù)阻塞及用戶體驗(yàn)差等問(wèn)題。

在這種劣勢(shì)情況下,到 2008 年 W3C 提出第一個(gè) HTML5 草案開始,就在 HTML5 中提出了Web Worker的概念,并規(guī)范了Web Worker的三大特征:

  • 能夠長(zhǎng)時(shí)間運(yùn)行
  • 理想的啟動(dòng)性能
  • 理想的內(nèi)存消耗

簡(jiǎn)介

Web Worker 是HTML5標(biāo)準(zhǔn)的一部分,這一規(guī)范定義了一套 API。實(shí)現(xiàn)了 用Web Worker 來(lái)實(shí)現(xiàn) JavaScript 的 “多線程” 技術(shù),并發(fā)執(zhí)行多個(gè) JavaScript 腳本。

Web Worker 與傳統(tǒng)多線程

每個(gè)JavaScript腳本執(zhí)行流都稱為一個(gè)線程,彼此之間互相獨(dú)立,并且有瀏覽器中的 JavaScript 引擎負(fù)責(zé)管理,當(dāng)然這并不是說(shuō)JavaScript支持多線程,雖然傳統(tǒng)JavaSript有多種方式實(shí)現(xiàn)了對(duì)多線程的模擬(例如:setinterval,setTimeout,以及一些異步的操作方法等),但是在本質(zhì)上程序的運(yùn)行仍然是由 JavaScript 引擎以單線程調(diào)度的方式運(yùn)行的,而Web Worker的線程是依賴于瀏覽器(宿主環(huán)境)來(lái)實(shí)現(xiàn)的,從而實(shí)現(xiàn)了對(duì)瀏覽器端多線程編程的支持。

Web Worker 線程種類

Web Worker 有兩種不同線程類型,分別是:

  • Dedicated Worker (專用線程)。只能被首次生成它的腳本使用
  • Shared Worker (共享線程)。可以同時(shí)被多個(gè)腳本使用

通常來(lái)說(shuō)的Web Worker指的就是Dedicated Worker,Service Worker也屬于其中,并且各大瀏覽器對(duì)其支持良好,而Shared Worker指的是SharedWorker,目前各大瀏覽器對(duì)其支持度較差。

這里主要對(duì)Dedicated Worker進(jìn)行詳細(xì)說(shuō)明,對(duì)于Shared Worker不再進(jìn)行細(xì)說(shuō)。

Worker模式



Worker線程執(zhí)行流



創(chuàng)建 Web Worker

下面說(shuō)一下如何創(chuàng)建一個(gè)Web Worker

語(yǔ)法:

new Worker(in DOMString aStringURL );

使用上面的方式即可以創(chuàng)建一個(gè)Web Worker對(duì)象,它執(zhí)行的是aStringURL中的腳本。目前大多數(shù)瀏覽器是支持data URI的aStringURL的,可以通過(guò)URL.createObjectURL(blob)創(chuàng)建。但需要注意的是腳本必須遵循同源策略。

下面創(chuàng)建一個(gè)Worker,Worker的執(zhí)行腳本是workerfile.js,創(chuàng)建成功后,它會(huì)返回一個(gè)新的Worker對(duì)象賦值給前面聲明的workerObj變量

var workerObj = new Worker('./workerfile.js');

這里需要注意, worker線程的創(chuàng)建的是異步的,主線程代碼不會(huì)阻塞在這里去等待worker線程去加載、執(zhí)行相應(yīng)的腳本文件,而是會(huì)立即向下執(zhí)行后面代碼。

Web Worker實(shí)例方法

Worker的實(shí)例方法只有兩個(gè):

  • postMessage
  • terminate

postMessage

主線程向生成的Worker線程發(fā)送數(shù)據(jù)的方法。

語(yǔ)法:

workerObj.postMessage(aMessage, transferList);
  • aMessage:向Worker線程發(fā)送的消息數(shù)據(jù)對(duì)象。它可以是任何類型的值或JavaScript對(duì)象。
  • transferList:可選。Transferable類型的數(shù)組。主要用在 ArrayBuffer, MessagePort, ImageBitmap對(duì)象。

注意:

postMessage發(fā)送的aMessage參數(shù),在傳遞通訊的時(shí)候會(huì)對(duì)數(shù)據(jù)進(jìn)行克隆,為了防止多個(gè)線程間的數(shù)據(jù)同時(shí)修改的問(wèn)題。實(shí)際上,瀏覽器內(nèi)部的實(shí)現(xiàn)是,先將通信傳遞的數(shù)據(jù)串行化,隨后把串行化后的數(shù)據(jù)發(fā)給子線程,后者再將數(shù)據(jù)還原。

postMessage也可以以二進(jìn)制的方式傳輸,例如 ArrayBuffer 、File、Blob、ImageBitmap等對(duì)象。但是往往傳輸?shù)倪@些對(duì)象數(shù)據(jù)量都很大,前面說(shuō)了傳輸數(shù)據(jù)會(huì)進(jìn)行拷貝,如果傳一個(gè)100MB的數(shù)據(jù),那么瀏覽器默認(rèn)會(huì)再?gòu)?fù)制一份100MB的數(shù)據(jù),導(dǎo)致一些不必要的資源消耗。為了防止這種問(wèn)題,就可以使用上面說(shuō)的第二個(gè)參數(shù)transferList來(lái)解決。

順道科普一下Transferable接口。這個(gè)接口代表一個(gè)能在不同可執(zhí)行上下文中相互傳遞的對(duì)象,例如主線程和Worker線程。

var arrBuff = new ArrayBuffer(8); myWorker.postMessage(arrBuff, [arrBuff]);

terminate

語(yǔ)法:

workerObj.terminate()

用于立即終止worker對(duì)象的行為,如果worker正在運(yùn)行著任務(wù)也會(huì)立即終止。

Web Worker實(shí)例屬性

Worker實(shí)例包含兩個(gè)屬性:

  • onmessage:用來(lái)接收worker線程傳遞過(guò)來(lái)的數(shù)據(jù)事件。
  • onerror:用來(lái)接收worker線程的錯(cuò)誤信息。

onmessage

onmessage屬性表示一個(gè)EventHandler事件處理函數(shù),當(dāng)Worker子線程返回一條消息時(shí)被調(diào)用。

語(yǔ)法:

workerObj.onmessage = function(e) { ... }

傳遞來(lái)的消息被封裝在事件的data屬性中。

workerObj.onmessage = function(e) {var result = e.data; }

onerror

onerror屬性是EventListener 一個(gè)事件監(jiān)聽函數(shù),一旦有類型為 error 的 ErrorEvent 從 worker線程中冒泡出來(lái)時(shí)就會(huì)執(zhí)行該函數(shù)。可以通過(guò)preventDefault()來(lái)取消冒泡。

主要用到的錯(cuò)誤屬性有:

  • message: 可讀的錯(cuò)誤信息
  • filename: 發(fā)生錯(cuò)誤的腳本文件名稱
  • lineno: 發(fā)生錯(cuò)誤的腳本所在文件的行數(shù)

Web Worker文件方法

Worker線程對(duì)象抽象于DedicatedWorkerGlobalScope接口。此作用域下沒有window對(duì)象,需要用self來(lái)調(diào)用。

在發(fā)送數(shù)據(jù)和接收數(shù)據(jù)使用的方法和worker實(shí)例對(duì)象的一樣:

  • postMessage
  • onerror

這兩個(gè)方法就不說(shuō)了,還有一個(gè)close方法說(shuō)一下。

close

這個(gè)和terminate()有點(diǎn)類似。這個(gè)方法主要用來(lái)清除所有在WorkerGlobalScope事件環(huán)中的排隊(duì)任務(wù),關(guān)閉特定作用域。

self.close()

importScripts 導(dǎo)入腳本

WorkerGlobalScope 對(duì)象中可以使用importScripts()方法來(lái)進(jìn)行對(duì)腳本文件和資源的引入。

但這個(gè)操作需要注意:

  • 如果沒有給 importScripts 方法任何參數(shù),那么立即返回,終止下面的步驟。
  • 解析 importScripts 方法的每一個(gè)參數(shù)。
  • 如果有任何失敗或者錯(cuò)誤,拋出 SYNTAX_ERR 異常。
  • 嘗試從用戶提供的 URL 資源位置處獲取腳本資源。
  • 對(duì)于 importScripts 方法的每一個(gè)參數(shù),按照用戶的提供順序,獲取腳本資源后繼續(xù)進(jìn)行其它操作。

Worker線程聲明周期

worker線程間的數(shù)據(jù)傳遞必須依賴于瀏覽器的context環(huán)境,通過(guò)MessagePort進(jìn)行傳遞數(shù)據(jù),所以每個(gè)worker線程的全局作用域都會(huì)有端口列表,并且會(huì)在WorkerGlobalScope中生成一個(gè)worker線程的線程列表,在初始化時(shí)為空。當(dāng)worker線程創(chuàng)建時(shí)會(huì)被填充進(jìn)去,當(dāng)worker線程終止時(shí)會(huì)從這個(gè)列表刪除。

worker線程中可調(diào)用的對(duì)象

在worker線程中,可以獲得下列對(duì)象:

  • navigator
  • location
  • XMLHttpRequest
  • setTimeout/setInterval
  • Application Cache
  • fetch
  • atob/btoa

等等。

實(shí)例

下面寫一個(gè)使用的小例子

html文件:

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title> </head> <body> <button id="btn">發(fā)送</button> <script>var worker = new Worker('./worker.js')btn.onclick = function(){worker.postMessage({a:1,b:2,c:3})}worker.onmessage = function(e){console.log('index-msg:', e)}worker.onerror = function(e) {console.log('index-err', e)e.preventDefault()} </script> </body> </html>

worker.js文件

self.onmessage = function(e) {console.log('worker in:', e)self.postMessage('get postMessage!') }

兼容性

還是有必要列一下Worker目前在瀏覽器上的兼容性:



可以看到支持的非常不錯(cuò)。

總結(jié)

可以看到Web Worker的出現(xiàn)使得在 Web 進(jìn)行多線程編程成為可能,對(duì)于高消耗、耗時(shí)長(zhǎng)的操作可以放到woker里面去進(jìn)行。

所以可以在以下應(yīng)用場(chǎng)景使用:

  • 使用專用線程進(jìn)行數(shù)學(xué)運(yùn)算
  • 圖像處理
  • 大量數(shù)據(jù)的檢索
  • 背景數(shù)據(jù)分析

等。


博客名稱:王樂(lè)平博客

CSDN博客地址:http://blog.csdn.net/lecepin

本作品采用知識(shí)共享署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際許可協(xié)議進(jìn)行許可。

總結(jié)

以上是生活随笔為你收集整理的PWA(Progressive Web App)入门系列:(五)Web Worker的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。