iT邦幫忙

DAY 27
8

HTML5試試看系列 第 27

[HTML5試試看-27] 多工 - WebWorkers

在瀏覽器中,Javascript雖然可以利用setTimeout或setInterval來達到非同步執行的效果,但是實際上所有的程式是共用一個event loop,在task queue裡面排隊執行的,並不是真正的多工。如果需要在一些應用中使用多工,那就需要WebWorker。
WebWorker有兩種:DedicatedWorker,只能讓一個Browser Context使用;而SharedWorker則可以與不同的Browser Context互動。要使用這兩種Worker很簡單,只要new一個就可以:

 var worker = new Worker('worker.js');
 var sharedworker = new SharedWorker('shared.js', 'name');

Worker是在獨立的Context中運作,擁有自己的Event Loop...使用Worker的關建在於怎樣與他溝通:

 worker.onmeswsage = function(e) {alert(e.data);};
 worker.postMessage('start');
 shared.port.onmessage = function(e) {alert(e.data);};
 shared.port.postMessage('start');

可以看到,在溝通機制上,DedicatedWorker與SharedWorker有些不同,後者必須透過MessageChannel機制。

接下來看一下到底在Worker的程式內可以做什麼。為了偵測Worker提供的GlobalScope裡面有哪些東西可以用,寫一個簡單的小程式,搭配Worker端的程式來做檢測:

...貼不下,放到paste.plurk.com跟gist上:
http://paste.plurk.com/show/325391
https://gist.github.com/666105

DedicatedWorker端的程式(test644.js):
http://paste.plurk.com/show/325392/
https://gist.github.com/666107

SharedWorker端的程式(test644a.js):

http://paste.plurk.com/show/325395/
https://gist.github.com/666109

執行一下,可以發現...IE9 Beta還沒有支援任何Worker...

Firefox4 Beta6只支援DedicatedWorker:

Safari兩個都有支援:

Opera同樣都有支援:

Chrome就不用說了:

想要在自己的瀏覽器跑跑看的話,可以用下面的網址:
http://www.fillano.idv.tw/test644.html

WebWorker規格書裡對於Worker的GlobalScope要提供哪些東西有起碼的規定。以DedicatedWorker來說,有:

  1. self:代表Worker的Global Scope的物件
  2. location:WorkerLocation物件,代表Worker物件的絕對網址。可以透過href, protocol, host, hostname, port, pathname, search, hash等屬性來取得相關的網址資訊。
  3. close():關閉worker
  4. onerror事件
    (以上定義在WorkerGlobalScope介面)
  5. postMessage():
  6. onmessage事件:透過這個事件接收網頁送來的資訊
    (以上定義在DedicatedWorkerGlobalScope介面)
  7. importScripts():可以使用這個方法載入其他的script
  8. navigator:他實作了NavigatorID及NavigatorOnline介面,所以會有appName, appVersion, platform, userAgent屬性可以取得瀏覽器資訊,另外透過onLine屬性可以知道目前是否離線。
    (以上定義在WorkerUtils介面)

對於SharedWorker來說,有:

  1. self:代表Worker的Global Scope的物件
  2. location:WorkerLocation物件,代表Worker物件的絕對網址。可以透過href, protocol, host, hostname, port, pathname, search, hash等屬性來取得相關的網址資訊。
  3. close():關閉worker
  4. onerror事件
    (以上定義在WorkerGlobalScope介面)
  5. name:可以取得瀏覽器在呼叫SharedWorker的constructor時,傳進去的name參數。
  6. applicationCache:就是會在離線應用時使用的ApplicationCache物件,不過Worker會有自己獨立的ApplicationCache,與產生SharedWorker網頁的ApplicationCache無關。
  7. onconnect事件:透過這個事件傳進來的MessageEvent,可以取得MessagePort來跟瀏覽器溝通。這個Event會有一個ports屬性,是一個MessagePort陣列。
    (以上定義在SharedWorkerGlobalScope介面)
  8. importScripts():可以使用這個方法載入其他的script
  9. navigator:他實作了NavigatorID及NavigatorOnline介面,所以會有appName, appVersion, platform, userAgent屬性可以取得瀏覽器資訊,另外透過onLine屬性可以知道目前是否離線。
    (以上定義在WorkerUtils介面)

不過其實許多HTML5相關API,也都有規定他們可以在Worker中實作。而且因為Worker是與瀏覽器完全獨立的,所以可以使用這些API的「同步」版本。例如FileReader就有提供一個FileReaderSync介面,可以使用同步的方式讀取檔案。

今天先簡單介紹這兩種Worker。其實DedicatedWorker至少在一年前就已經有瀏覽器內建了,我在去年的鐵人賽也有介紹過,所以就暫時不測試他,明天會把火力集中在SharedWorker。

參賽文章


上一篇
[HTML5試試看-26] GeoLocation
下一篇
[HTML5試試看-28] 多工 - SharedWorker
系列文
HTML5試試看30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
pantc328
iT邦高手 1 級 ‧ 2010-11-08 08:34:36

看你寫那麼多篇,雖然我沒特別看內容.
HTML5真的變很多.
但我不曉得這世上怎麼那麼多瀏覽器?
也不曉得為什麼很多企業客戶還在用IE6那種舊瀏覽器.
所以還是用以前的就方式,遇到什麼解什麼了.

0
fillano
iT邦超人 1 級 ‧ 2010-11-08 09:44:24

前端最快解法是使用像jQuery這樣的library,他做了一層抽象來解決跨瀏覽器以及向上相容的問題,不過也不敢保證百分之百。最近的版本好像都有一點問題(1.4.2/1.4.3)...

jQuery釋出前應該都有做跨瀏覽器與跨版本的測試,他們之前還為這樣的測試開發測試工具,所以基本上是可以信賴的,但是還是需要測試XDDD

IE5跟IE6出來的時候,都是「很好,很強大」的,我在離線應用的例子裡面有一個2.5D地圖行走的小網頁,最早的版本之一就是IE5 Only,不過是基於「效能」跟鍵盤事件支援的因素。不過IE6實在用太久...然後又很多人用IE Only的方式開發...

HTML5的話,目前瀏覽器廠商都預期會全力支援,所以未來應該可以比較樂觀,只要沒有IE幽靈作祟...

我要留言

立即登入留言