全文共2548字,預計學習時長8分鐘
來源:Pexels
多年以來,JavaScript最麻煩的特征之一就是,如果某個任務耗時太長,剩下的代碼就會遇到阻塞而無法運行。
JavaScript是單線程的編程語言,這一特點導致用戶需要等待代碼按照順序運行。
但事實上有一種方式可以避免這種困境,它就是Worker。
在本文中,小芯將介紹Worker的使用方式。
閱讀之前讀者需要知道JavaScript是一種單線程語言。
同步編碼先來看看讀者可能已經熟知的JavaScript代碼樣式
let cnt = 0;for (let i = 0; i < 10e8; i += 1) { cnt += 1;}console.log(cnt);
在這段代碼的for循環中,cnt每次增加1,總共增加了次。而console.log要等到for循環結束后才能執行。
在Chrome瀏覽器控制臺中,這需要花費很長時間。
這段代碼需要耗費將近3秒。
無論如何,直到for循環結束cnt才會打印出來。
許多開發者都被這個問題困擾,因為用戶必須等待當前執行的任務完成。
異步代碼來源:Pexels
JavaScript的設計者為開發者提供了不會阻塞程序流的特殊函數。這些函數處于和普通任務不同的等待隊列中。一般而言,它們可以在所有普通程序執行之后再執行。這些任務被稱為異步任務。
let cnt = 0;tTimeout(() => { for (let i = 0; i < 10e8; i += 1) { cnt += 1; } console.log(cnt);});console.log(cnt);
這段代碼的運行結果和前面一段有所不同。
但仍然需要等待較長的時間。
這里的for循環包含在 tTimeout中. tTimeout中的代碼會等待所有普通任務完成后再執行。
但這并非解決代碼流堵塞問題的最佳方案。雖然 tTimeout是一個不阻礙正常代碼流的異步函數,但是這樣做僅僅改變了函數的執行順序。
let cnt = 0;tTimeout(() => { for (let i = 0; i < 10e8; i += 1) { cnt += 1; } console.log(cnt);});tTimeout(() => { console.log(cnt);});console.log(cnt);
看看這個例子,其中使用了另一個tTimeout,它包含一個立即打印cnt的函數。然而第二個tTimeout總是在第一個tTimeout結束for循環后才開始運行console.log(cnt)指令。如果第一個tTimeout包含的任務耗時較長,那么第二個tTimeout將無法運行。
為什么?因為Javascript是一種單線程編程語言。異步函數存在于不同的任務隊列中,但它們仍然遵循單線程規則。
WorkersWeb Worker是一種網絡接口,這意味著它無法訪問或管理文檔對象模型。Worker存在于一個不同的線程中,它和主線程互不干擾。它在一個新的Worker對象創建時接受信息,然后向worker發送信息。
let worker;if ('Worker' in window) { worker = new Worker('file_name');}
創建新的Worker實例十分簡單。new Worker這條指令接受一個字符串或者超鏈接作為參數。這個參數的格式一般如下所示:
new Worker('/worker.js');
實例創建之后,可以向另一個線程發送信息。
worker.postMessage('From Main Thread');
于是可以在worker所處的線程中收到這個信息。
// worker.jsthis.addEventListener('message', event => { console.log(event.data);});
Worker成功接受信息。
如果仔細查看日志,會發現文件名是worker.js而不是main.js或者app.js。這說明worker接受了完好的信息。
現在,讓worker在收到主線程信息的同時也向主線程發送一條信息。
// main.jsworker.addEventListener('message', event => { console.log(event.data);});// worker.jsthis.addEventListener('message', event => { ... this.postMessage('From Worker Thread');});
這段代碼看起來有些冗余。讀者將會看到其工作流,但是首先來看看結果。
現在能看到兩條信息。
這段代碼是如何工作的呢?
onMessage代表從線程另一端接受信息這一事件,postMessage則代表向線程另一端發送信息這一事件。
代碼測試在這個測試中可以看到兩點。
· For循環的運行總時長
· 代碼阻斷
這個示例使用React制作。狀態消息應該按照預期打印,然而同步和異步行為不會打印除了總運行時長外的任何信息。因為在React中,狀態改變也是一種異步行為,需要等待普通任務和其他前序異步任務完成才能執行。
另一方面,worker不需要等待,因為它位于另一個線程中。For循環在worker線程中,異步任務則在主線程中,所以它們不會互相打斷。
結論來源:Pexels
通常worker被用于占用大量CPU資源的程序中,比如2D canvas 和矢量圖。因為worker位于另一個線程中,它不會阻斷主線程中的任何任務,比如UI渲染。如果能將worker運用自如,它的效果將十分強大。包括IE10在內的眾多瀏覽器都能夠很好地支持這一功能。
留言點贊關注
我們一起分享AI學習與發展的干貨
如轉載,請后臺留言,遵守轉載規范
本文發布于:2023-02-28 20:14:00,感謝您對本站的認可!
本文鏈接:http://m.newhan.cn/zhishi/a/167766506882507.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
本文word下載地址:worker(worker怎么讀音發音).doc
本文 PDF 下載地址:worker(worker怎么讀音發音).pdf
| 留言與評論(共有 0 條評論) |