跳到主要內容

【Web微知識系列】關於網頁上的多工技術Web Workers

 越來越多的應用都在網頁上完成了,猶如過往的Excel、Word,現在都能直接用網頁來編輯使用,但我們想過嗎? 所有的運算,除了伺服器以外,網頁是不是也會有一些複雜的計算呢? 那對於這些複雜的計算,如果讓整個網頁卡住,勢必會影響到使用者的體驗,因此系統運算中的多工技術也被搬移到網頁端了,讓使用者一邊可以正常使用,背後將多餘的資源拿來進行較為複雜的計算。

但網頁端主要使用的語言是Javascript,原本的主要目的是簡單的互動,因此設計為單執行序,但隨著時代的演進,越來越多的功能都依賴這樣的程式進行運算,詳細我們將逐一說明。

為什麼javascript要設計為單執行緒?

javascript主要功能是與user操作頁面互動及操作dom,試想若使用多執行緒的概念,那麼一個動作是新增至某個dom節點,另一個動作則是修改該dom節點,此時瀏覽器應該使用哪個動作為準? 所以為了避免複雜性才設計為單執行緒。

理解javascript非同步的概念

單執行緒就表示說所有任務都需要排隊處理,相對的效率較低落,IO或Network request通常需要等待較長的時間,如果前端頁面常常因為這些動作發生堵塞則user看到的畫面就是整個鎖死的,因此javascript使用了一些機制來避免這個問題,主要將任務分為兩種:

● 同步任務: 主執行緒上排隊執行的任務。
● 異步任務: 不進入主執行緒,而是進入任務佇列等待執行。

上圖的執行機制

1. 主程序會先從stack中執行function
2. 執行過程中遇到setTimeout這類的非同步API呼叫,會透過事件委託的機制掛一個callback到setTimeout之類的Web API,執行完畢後會將該callback傳入上圖的callback queue等待。
3. 執行堆棧空閒時才從callback queue中取出任務執行。
4. 因此我們才會使用setTimeout的技巧讓一些需要長時間計算的任務排到任務佇列中等待,然而主執行緒就不會因為這個任務發生阻塞現象,可以先執行觸發loading動畫的事件後才處理這些耗時的任務,讓user感覺到畫面並非被鎖死。

上面的技巧雖然解決了畫面被鎖死的問題,但實際上執行的時間並沒有減少,因此發展出了Web Worker的機制,讓我們在web上也能有多執行緒的功能,最大化的利用系統資源,但是仍有部分功能受限。

Web Workers的類型

Web Workers依照用途又分為Dedicated workers與Shared workers

● Dedicated workers: 只能與產生它的頁面相互溝通。
● Shared workers: 只要是相同來源(分頁、iframe)上執行的程序都能夠相互溝通。

應用的情境

一般狀況下或許我們不需要Web Workers來處理程式執行過久的情境,但是若能運用Web Workers或許能將部分Server的運算工作轉移至前端執行,以下是一些大量運算的使用情境:

● 解密等複雜的數學運算。
● 排序大量的array。
● 緩存資料。
● 語法高亮標記、拼音檢查。
● 影像、視訊、音頻的解析處理。
● polling web services。

Work中常用的方法

● postMessage(data): 子線程與主線程之間相互溝通的方法,傳遞的data為任意值。
● onmessage: 監聽線程之間message的傳遞,當線程之間觸發postMessage時,能夠藉由onmessage順利接收傳遞的資料。
onerror:常用於debug。
● terminate(): 主線程中終止worker任務的API,一旦終止後不能再次啟用,只能重新創建。

使用上的限制

Web Workers因為安全性問題所以使用上需要有一些使用上的限制:

● 無法訪問主頁面的dom結構。
● 無法使用全域變數或者全域函數。
● 無法使用window或document。
● 不能傳遞functions。

開始使用Web Workers

這裡主要針對 Dedicated workers示範使用方式,而 Shared workers操作方式大致上相同於 Dedicated workers 因此僅需要了解概念即可。

首先需要檢查瀏覽器是否支援Web Workers

function isWebWorkerSupport() {
return typeof Worker !== “undefined”;
}
if (isWebWorkerSupport()) {
….
} else {
alert(“Ops, your browser doesn’t support Web Worker”);
}

簡單的創建一個Worker

var worker = new Worker(“worker.js”);

與Worker之間的溝通方式

<main.js>

//傳遞消息給worker這裡可以是array、string、number等型態
worker.postMessage(“Send to worker”);
//監聽message事件,接收worker回報的訊息
worker.onmessage = function(e) {
console.log(e.data);
}

<worker.js>

self.onmessage = function(e) {
//處理複雜運算完成後回報運算結果或者通知
self.postMessage(“finished”);
}

終止worker工作

當每個worker thread完成工作時記得終止,讓瀏覽器能夠釋放資源。

worker.terminate();

結語

不知道這樣的知識分享對各位薯友來說會不會太艱深了,嘗試將自己所學的技術分享給有需要的朋友,這也是首次以比較技術的方式進行文章撰寫,過程也期望得到一些反饋。

喜歡撰寫文章的你,不妨來了解一下:




Web3.0時代下為創作者、閱讀者打造的專屬共贏平台 - 為什麼要加入?

留言

這個網誌中的熱門文章

java西元民國轉換_各種不同格式

C#資料庫操作(新增、修改、刪除、查詢)

【Excel好好玩】 自己的資產自己管!善用Google Sheet來幫我們評估貸款

這次介紹的主題是關於Excel的貸款還款計畫試算,我們人生中總會遇到需要大筆金額的花費,但當資金不夠時就得進行貸款,而貸款之前如果我們能夠審慎評估,並分析自己的還款能力之後在進行凍作,相信風險會小很多,因此就自己動動手來使用Google Sheet進行試算吧! 基本資料 ● 貸款總額: 1000000 ● 貸款期數: 84月 ● 年利率: 2.11% ● 月利率: 0.18% P.S 月利率 = 年利率 / 12 重要函式 PMT : 這是Google Sheet內建的重要年金計算公式,我們可以善用這個公式來計算固定利率及期數的固定攤還本息。因為PMT函式計算出的結果為負數,所以前面加上-號轉成正數。 動手做 首先我們在Excel表上列出我們的基本資料 圖片來源 其中月利率的部分就使用公式「=B4/12」 接著我們填上第一列的期數跟餘額 圖片來源 =B2 =B3 使用關鍵PMT函數來計算本息的部分 因為PMT函式計算出的結果為負數,所以前面加上-號轉成正數。 -PMT(貸款利率(月利率), 貸款期數, 貸款總額) =-PMT($B$5,$B$3,$B$2) 圖片來源 計算利息 利息 = 貸款餘額 x 月利率 =B8*$B$5 圖片來源 計算本金 本金 = 本息 - 利息 =C8-D8 圖片來源 製作第二列餘額的部分 餘額的部分 = 上一期的餘額 - 上一期的本金 圖片來源 接著拖曳該兩列往下拉,即可查看每一期的利息與本金 圖片來源 結語 雖然市面上已經有很多貸款銀行都提供了試算功能,但如果我們想要進一步管理自己的資產時,就需要將每一期的金額給計算出來,因此才會將公式運用在Excel表,讓我們的資產管理表能夠結合負債,進一步評估我們理財行動的下一步,希望這樣的經驗可以幫助到正在理財道路上打拼的夥伴,讓我們透過有效的管理,幫助荷包長大吧! 喜歡撰寫文章的你,不妨來了解一下: Web3.0時代下為創作者、閱讀者打造的專屬共贏平台 — 為什麼要加入? 歡迎加入一起練習寫作,賺取知識,累積財富!