摘要:專(zhuān)用線程不僅僅支持傳輸二進(jìn)制數(shù)據(jù),也支持結(jié)構(gòu)化的數(shù)據(jù)格式。但是我們所開(kāi)啟的新的也就是子線程,并不支持操作頁(yè)面的。共享線程共享線程是為了避免線程的重復(fù)創(chuàng)建和銷(xiāo)毀過(guò)程,降低了系統(tǒng)性能的消耗,共享線程可以同時(shí)有多個(gè)頁(yè)面的線程鏈接。
原文鏈接
Web Worker 詳細(xì)介紹 - 原文鏈接
[TOC]
1、簡(jiǎn)介我們都知道JavaScript這個(gè)語(yǔ)言在執(zhí)行的時(shí)候是采用單線程進(jìn)行執(zhí)行的,也就是說(shuō)在同一時(shí)間只能做一件事,這也和這門(mén)語(yǔ)言有很大的關(guān)系,采用同步執(zhí)行的方式進(jìn)行運(yùn)行,如果出現(xiàn)阻塞,那么后面的代碼將不會(huì)執(zhí)行,HTML5則提出了web Worker標(biāo)準(zhǔn),表示JavaScript允許有多個(gè)線程,但是子線程完全受主線程的控制,切子線程不能操作DOM,只有主線程可以操作DOM,所以以主線程為主的單線程執(zhí)行原理成了JavaScript這門(mén)語(yǔ)言的核心。關(guān)于JavaScript的運(yùn)行機(jī)制可以參考阮一峰的文章JavaScript 運(yùn)行機(jī)制詳解:再談Event Loop
2、Web Worker下面我們來(lái)說(shuō)說(shuō)web worker到底是什么,簡(jiǎn)單明了的一句話其實(shí)就是在Javascript單線程執(zhí)行的基礎(chǔ)上,開(kāi)啟一個(gè)子線程,進(jìn)行程序處理,而不影響主線程的執(zhí)行,當(dāng)子線程執(zhí)行完畢之后再回到主線程上,在這個(gè)過(guò)程中并不影響主線程的執(zhí)行過(guò)程。
舉個(gè)例子:
傳統(tǒng)情況下,執(zhí)行下面的代碼后,整個(gè)頁(yè)面都會(huì)被凍結(jié),由于javascript是單線程處理,如下代碼已經(jīng)完全組塞了后續(xù)的執(zhí)行
while(true){}
如果換一種方式,我們通過(guò)開(kāi)啟一個(gè)新的線程來(lái)執(zhí)行這段代碼,將他放在一個(gè)多帶帶的worker.js文件中,在主線程執(zhí)行以下代碼。
var worker = new Worker("worker.js")
在創(chuàng)建線程的時(shí)候需要給實(shí)例化的Worker傳入唯一一個(gè)參數(shù),指向一個(gè)javascript文件資源的url或者Blob對(duì)象(Blob對(duì)象就是一個(gè)包含有只讀原始數(shù)據(jù)類(lèi)文件對(duì)象),調(diào)用這個(gè)構(gòu)造函數(shù)之后,一個(gè)線程就被創(chuàng)建了,如下:
var worker = new Worker("worker.js"); var worker = new Worker(blob);
Web Worker的基本原理就是在當(dāng)前的主線程中加載一個(gè)只讀文件來(lái)創(chuàng)建一個(gè)新的線程,兩個(gè)線程同時(shí)存在,且互不阻塞,并且在子線程與主線程之間提供了數(shù)據(jù)交換的接口postMessage和onmessage。來(lái)進(jìn)行發(fā)送數(shù)據(jù)和接收數(shù)據(jù)。其數(shù)據(jù)格式可以為結(jié)構(gòu)化數(shù)據(jù)(JSON等);
當(dāng)我們創(chuàng)建了一個(gè)worker實(shí)例之后,我們可以通過(guò)如下兩種方式來(lái)發(fā)送數(shù)據(jù):
var worker = new Worker("worker.js"); //實(shí)例化對(duì)象 //第一種傳遞方式 worker.postMessage(message,taransferList); //第二種傳遞方式 worker.postMessage({ operation: "list_all_users", //ArrayBuffer object input: buffer, threshold: 0.8, }, [buffer]);
如果要想一個(gè)專(zhuān)用線程發(fā)送數(shù)據(jù),那么我們需要使用線程中的 postMessage 方法。專(zhuān)用線程不僅僅支持傳輸二進(jìn)制數(shù)據(jù),也支持結(jié)構(gòu)化的 JavaScript 數(shù)據(jù)格式。在這里有一點(diǎn)需要注意,為了高效地傳輸 ArrayBuffer 對(duì)象數(shù)據(jù),需要在 postMessage 方法中的第二個(gè)參數(shù)中指定它。
同時(shí)我們?nèi)绻枰邮漳硞€(gè)線程傳來(lái)的數(shù)據(jù)可以使用onmessage來(lái)進(jìn)行接收,方法如下:
//方法一 worker.onmessage = function(event){ var data = event.data; //通過(guò)event.data來(lái)獲取傳入的參數(shù) } //方法二 worker.addEventListener("message",target);
下面是一段運(yùn)行在chrome中的參數(shù)傳遞方式:
index.html
webWorker
worker.js
onmessage = function (e) { console.log(e.data); postMessage("2222") };
此時(shí)我們的瀏覽器打印出的log是如下:
上面我們已經(jīng)說(shuō)了創(chuàng)建一個(gè)新的線程、傳遞數(shù)據(jù)、接收數(shù)據(jù)的方法,下面再次做一個(gè)精簡(jiǎn)的回顧。
var worker = new Worker("worker.js")
worker.postMessage("text");
worker.onmessage = function (e) { var message = e.data; };
worker.onerror = function(e){ console.log("error at "+e.filename ":" + e.lineno + e.message) }
worker.terminate();
importScripts("./utils/base64.js","./utils/map.js"...)
需要注意的是importScripts是同步方法,一旦importScripts方法返回就可以開(kāi)始使用載入的腳本,而不需要回調(diào)函數(shù)。4、Worker作用域
當(dāng)我們創(chuàng)建一個(gè)新的worker時(shí),改代碼會(huì)運(yùn)行在一個(gè)全新的javascript的環(huán)境中(WorkerGlobalScope)運(yùn)行,是完全和創(chuàng)建worker的腳本隔離,這時(shí)我們可以吧創(chuàng)建新worker的腳本叫做主線程,而被創(chuàng)建的新的worker叫做子線程。
WorkerGlobalScope是worker的全局對(duì)象,所以它包含所有核心javascript全局對(duì)象擁有的屬性如JSON等,window的一些屬性,也擁有類(lèi)似于XMLHttpRequest()等。
但是我們所開(kāi)啟的新的worker也就是子線程,并不支持操作頁(yè)面的DOM。
5、共享線程 SharedWorker共享線程是為了避免線程的重復(fù)創(chuàng)建和銷(xiāo)毀過(guò)程,降低了系統(tǒng)性能的消耗,共享線程SharedWorker可以同時(shí)有多個(gè)頁(yè)面的線程鏈接。
使用SharedWorker創(chuàng)建共享線程,也需要提供一個(gè)javascript腳本文件的URL地址或Blob,該腳本文件中包含了我們?cè)诰€程中需要執(zhí)行的代碼,如下:
var worker = new SharedWorker("sharedworker.js");
共享線程也使用了message事件監(jiān)聽(tīng)線程消息,但使用SharedWorker對(duì)象的port屬性與線程通信如下。
worker.port.onmessage = function(e){ ... }
同時(shí)我們也可以使用SharedWorker對(duì)象的port屬性向共享線程發(fā)送消息如下。
worker.port.postMessage("message");摘錄
文章大部分類(lèi)容摘自《指尖上行》一書(shū)
參考文獻(xiàn)
1、JavaScript 運(yùn)行機(jī)制詳解:再談Event Loop —— 阮一峰
2、深入 HTML5 Web Worker 應(yīng)用實(shí)踐:多線程編程
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90341.html
摘要:在上看到發(fā)的視頻被狂轉(zhuǎn)開(kāi)始注意之前幾乎對(duì)這個(gè)詞語(yǔ)沒(méi)有印象看到是在的演講還以為是新技術(shù)在上找一下這次好多個(gè)視頻是關(guān)于的視頻的內(nèi)容主要是講網(wǎng)站優(yōu)化分別用做例子可惜沒(méi)有大概要等小右補(bǔ)方案應(yīng)該沒(méi)有問(wèn)題從視頻看優(yōu)化的效果非常顯著本來(lái)好幾秒的 在 Twitter 上看到 Addy Osmani 發(fā)的視頻被狂轉(zhuǎn), 開(kāi)始注意https://twitter.com/addyosmani/status/7...
摘要:的另一個(gè)核心特性,蘋(píng)果表示也正在開(kāi)發(fā)中,按開(kāi)發(fā)進(jìn)度可能幾個(gè)月后就能與我們見(jiàn)面。是基于的本地化數(shù)據(jù)庫(kù),支持以及瀏覽器環(huán)境。 前端每周清單專(zhuān)注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開(kāi)發(fā)教程、工程實(shí)踐、深度閱讀、開(kāi)源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(hào)(ID: frontshow),及時(shí)獲取前端每周清單。 本期是 2017 年的最后一...
摘要:前端每周清單專(zhuān)注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開(kāi)發(fā)教程工程實(shí)踐深度閱讀開(kāi)源項(xiàng)目巔峰人生等欄目。 前端每周清單專(zhuān)注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開(kāi)發(fā)教程、工程實(shí)踐、深度閱讀、開(kāi)源項(xiàng)目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(hào)(ID:frontshow),及時(shí)獲取前端每周清單;本文則是對(duì)于...
摘要:背景前一陣子開(kāi)發(fā)的項(xiàng)目導(dǎo)入由于自己的代碼問(wèn)題引起了個(gè)性能問(wèn)題一個(gè)的文件轉(zhuǎn)換成數(shù)據(jù)大概要耗時(shí)雖然后面發(fā)現(xiàn)是某個(gè)使用頻率非常高的函數(shù)內(nèi)部用了構(gòu)造函數(shù)造成的所以這里順便提醒一下如果你很在乎幾毫秒的差距的話建議謹(jǐn)慎使用哈但是在優(yōu)化的過(guò)程中一度懷疑是 背景 前一陣子開(kāi)發(fā)的項(xiàng)目 pptx 導(dǎo)入, 由于自己的代碼問(wèn)題,引起了個(gè)性能問(wèn)題,一個(gè) 40p 的 pptx 文件,轉(zhuǎn)換成 json 數(shù)據(jù),大概要...
閱讀 2463·2021-11-11 16:54
閱讀 1244·2021-09-22 15:23
閱讀 3701·2021-09-07 09:59
閱讀 2039·2021-09-02 15:41
閱讀 3315·2021-08-17 10:13
閱讀 3095·2019-08-30 15:53
閱讀 1270·2019-08-30 13:57
閱讀 1240·2019-08-29 15:16