http://www.javashuo.com/article/p-mqjznazm-g.htmljavascript
http://www.javashuo.com/article/p-xvypszop-h.htmlhtml
傳統上的線程能夠解釋爲輕量級進程,它和進程同樣擁有獨立的執行控制,通常狀況下由操做系統負責調度。而在 HTML5 中的多線程是這樣一種機制,它容許在 Web 程序中併發執行多個 JavaScript 腳本,每一個腳本執行流都稱爲一個線程,彼此間互相獨立,而且由瀏覽器中的 JavaScript 引擎負責管理。下面咱們將詳細講解 HTML5 的工做線程原理。java
Web Workers 是瀏覽器內置的線程因此能夠被用來執行非阻塞事件循環的 JavaScript 代碼。node
在 HTML5 中引入的工做線程使得瀏覽器端的 JavaScript 引擎能夠併發地執行 JavaScript 代碼,從而實現了對瀏覽器端多線程編程的良好支持。將可能耗費較長時間的處理交給後臺執行,則對用戶在前臺頁面中執行的操做沒有影響。git
HTML5 中的 Web Worker 能夠分爲兩種不一樣線程類型,一個是專用線程 Dedicated Worker,一個是共享線程 Shared Worker。兩種類型的線程各有不一樣的用途。github
應用場景一:使用工做線程作後臺數值複雜(算法)計算web
應用場景二:使用共享線程處理多用戶併發鏈接算法
應用場景三:高頻的用戶交互編程
應用場景四:監聽由後臺服務器廣播的消息canvas
//worker.js
onmessage =function (evt){
var d = evt.data;//經過evt.data得到發送來的數據
postMessage( d );//將獲取到的數據發送會主線程
}
HTML頁面:test.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript">
//WEB頁主線程
var worker =new Worker("worker.js"); //建立一個Worker對象並向它傳遞將在新線程中執行的腳本的URL
worker.postMessage("hello world"); //向worker發送數據
worker.onmessage =function(evt){ //接收worker傳過來的數據函數
console.log(evt.data); //輸出worker發送來的數據
}
</script>
</head>
<body></body>
</html>
WEB主線程:
1.經過 worker = new Worker( url ) 加載一個JS文件來建立一個worker,同時返回一個worker實例。
2.經過worker.postMessage( data ) 方法來向worker發送數據。
3.綁定worker.onmessage方法來接收worker發送過來的數據。
4.可使用 worker.terminate() 來終止一個worker的執行。
worker新線程:
1.經過postMessage( data ) 方法來向主線程發送數據。
2.綁定onmessage方法來接收主線程發送過來的數據。
加載一個JavaScript文件,進行大量的複雜計算,而不掛起主進程,並經過postMessage和onMessage進行通訊。
能夠在WoOer(worker)中經過importScripts(url)方法加載另外的JavaScript腳本文件。
可使用setTimeout()、clearTimeout()、setInterval()和clearInterval()。
可使用XMLHttpRequest進行異步請求。
能夠訪問navigator的部分屬性。
可使用JavaScript核心對象。
監聽由後臺服務器廣播的消息。
1.不能跨域加載JS
2.worker內代碼不能訪問DOM()、window
對象、document
對象、parent
對象
3.各個瀏覽器對Worker的實現不大一致,例如FF裏容許worker中建立新的worker,而Chrome中就不行
4.不是每一個瀏覽器都支持這個新特性
•navgator : ppVersion、userAgent、platform
•location : 全部屬appName、a性都是隻讀的
•self : 指向全局 worker 對象
•全部的ECMA對象,Object、Array、Date等
•XMLHttpRequest構造器
•setTimeout和setInterval方法
•close()方法,馬上中止worker運行
•importScripts方法
迄今爲止,咱們列舉了 Web Workers 的長處及其限制。讓咱們看看他們的最佳使用場景:
這裏須要注意的是在現代瀏覽器已經不支持同步接口了,具體可查看這裏。
實際工做過程會遇到用戶須要經過解析遠程圖片來得到圖片 base64 的案例,那麼這時候,若是圖片很是大,就會形成 canvas 的 toDataURL
操做至關的耗時,從而阻塞頁面的渲染。
因此解決思路即把這裏的處理圖片的操做交由 worker 來處理。如下貼出主要的代碼:
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <title>Canvas to base64</title> </head> <body> <script> function loadImageAsync(url) { if (typeof url !== 'string') { return Promise.reject(new TypeError('must specify a string')); } return new Promise(function(resolve, reject) { const image = new Image(); // 容許 canvas 跨域加載圖片 image.crossOrigin="anonymous"; image.onload = function() { const $canvas = document.createElement('canvas'); const ctx = $canvas.getContext('2d'); const width = this.width; const height = this.height; let imageData; $canvas.width = width; $canvas.height = height; ctx.drawImage(image, 0, 0, width, height); imageData = ctx.getImageData(0, 0, $canvas.width, $canvas.height); resolve({image, imageData}); }; image.onerror = function() { reject(new Error('Could not load image at ' + url)); }; image.src = url; }); } function blobToDataURL(blob) { return new Promise((fulfill, reject) => { let reader = new FileReader(); reader.onerror = reject; reader.onload = (e) => fulfill(reader.result); reader.readAsDataURL(blob); }) } document.addEventListener("DOMContentLoaded", function () { loadImageAsync('https://cdn-images-1.medium.com/max/1600/1*4lHHyfEhVB0LnQ3HlhSs8g.png') .then(function (image) { // jpeg-web-worker.js https://github.com/kentmw/jpeg-web-worker const worker = new Worker('jpeg-web-worker.js'); worker.postMessage({ image: image.imageData, quality: 50 }); worker.onmessage = function(e) { // e.data is the imageData of the jpeg. {data: U8IntArray, height: int, width: int} // you can still convert the jpeg imageData into a blog like this: const blob = new Blob( [e.data.data], {type: 'image/png'} ); blobToDataURL(blob).then((imageURL) => { console.log('imageUrl:', imageURL); }) } }) .catch(function (err) { console.log('Error:', err.message); }); }); </script> </body> </html>
以上是經過 canvas 來獲取圖片數據,那麼是否有其它方法呢?確定有的啦,動下腦筋吧少年。