JavaScript 多線程Web Worker && 在Vue中如何使用

概述

Web Workerhtml5 的新特性竭宰,JavaScript 是單線程模型莺禁,所有任務(wù)只能在一個線程上完成松蒜,一次只能做一件事丢氢。前面的任務(wù)沒做完,后面的任務(wù)只能等著裕寨, 在某些場景下很不方便浩蓉,Web Worker 的作用派继,就是為 JavaScript 創(chuàng)造多線程環(huán)境,允許主線程創(chuàng)建 Worker 線程捻艳,將一些任務(wù)分配給后者運行驾窟。在主線程運行的同時,Worker 線程在后臺運行认轨,兩者互不干擾绅络。等到 Worker 線程完成計算任務(wù),再把結(jié)果返回給主線程嘁字。這樣的好處是恩急,一些計算密集型或高延遲的任務(wù)可以交由 Worker 線程執(zhí)行,主線程能夠保持流暢纪蜒,不會被阻塞或拖慢衷恭。
Worker 線程一旦新建成功,就會始終運行纯续,不會被主線程上的活動(比如用戶點擊按鈕匾荆、提交表單)打斷。這樣有利于隨時響應(yīng)主線程的通信杆烁。但是牙丽,這也造成了 Worker比較耗費資源,不應(yīng)該過度使用兔魂,而且一旦使用完畢烤芦,就應(yīng)該關(guān)閉

使用場景

任何需要始終運行的js代碼都可以使用Worker , 比如定時器析校,當(dāng)頁面處于不可見狀態(tài)時构罗,定時器的執(zhí)行間隔會擴大,這樣會造成一些程序的執(zhí)行異常智玻,此時就可以使用webWorkers來解決

使用方法

  1. 線程創(chuàng)建
    專用線程由 Worker() 方法創(chuàng)建遂唧,可以接收兩個參數(shù),第一個參數(shù)是必填的腳本的位置吊奢,第二個參數(shù)是可選的配置對象盖彭,可以指定 typecredentials页滚、name三個屬性
var worker = new Worker('worker.js')

共享線程使用 Shared Worker() 方法創(chuàng)建召边,同樣支持兩個參數(shù),用法與 Worker() 一致裹驰。

var sharedWorker = new SharedWorker('shared-worker.js')

注意: 因為 Web Worker 有同源限制隧熙,所以在本地調(diào)試的時候也需要通過啟動本地服務(wù)器的方式訪問,使用 file:// 協(xié)議直接打開的話將會拋出異常幻林,且Worker線程不能執(zhí)行alert()方法和confirm()方法贞盯,但可以使用XMLHttpRequest對象發(fā)出 AJAX 請求

  1. Worker 線程和主線程之間的通信
    Worker 線程和主線程都通過 postMessage() 方法發(fā)送消息音念,通過 onmessage 事件接收消息。在這個過程中數(shù)據(jù)并不是被共享的躏敢,postMessage() 一次只能發(fā)送一個對象症昏, 如果需要發(fā)送多個參數(shù)可以將參數(shù)包裝為數(shù)組或?qū)ο笤龠M(jìn)行傳遞
// 主線程
var worker = new Worker('worker.js')
worker.postMessage([10, 24])
worker.onmessage = function(e) {
    console.log(e.data)
}

// Worker 線程
onmessage = function (e) {
    if (e.data.length > 1) {
        postMessage(e.data[1] - e.data[0])
    }
}

Worker 線程中,selfthis 都代表子線程的全局對象父丰。對于監(jiān)聽 message 事件,以下的四種寫法是等同的

// 寫法 1
self.addEventListener('message', function (e) {
    // ...
})

// 寫法 2
this.addEventListener('message', function (e) {
    // ...
})

// 寫法 3
addEventListener('message', function (e) {
    // ...
})

// 寫法 4
onmessage = function (e) {
    // ...
}
  1. **關(guān)閉 Worker **
// 主線程
worker.terminate()

// Dedicated Worker 線程中
self.close()

// Shared Worker 線程中
self.port.close()

在vue中使用Worker

首先要安裝laoder

npm i -D worker-loader

vue.config.js中配置以下

module.exports = {
  // ...
  chainWebpack(config) {
    config.module
      .rule('worker')
      .test(/\.worker\.js$/)
      .use('worker-loader')
      .loader('worker-loader')
      .end();
    config.module.rule('js').exclude.add(/\.worker\.js$/)
  },
  parallel: false,
  // chainWebpack: config => {
  //   // 解決:“window is undefined”報錯掘宪,這個是因為worker線程中不存在window對象蛾扇,因此不能直接使用,要用this代替
  //   config.output.globalObject('this')
  // }
}

配置了之后 worker.js 后綴的文件就會被 loader 處理

// 在timer.worker.js
let count = 0
// 接收主線程的消息
self.addEventListener('message', (e) => {
  count = e.data
  self.postMessage(count--)
}, false)
// 用定時器發(fā)消息
setInterval(() => {
  // postMessage 用于數(shù)據(jù)交互
  self.postMessage(count)
  count--
}, 1000)

// 在vue中
import Worker from './prompt.worker.js'

mounted() {
  this.worker = new Worker()
  this.worker.postMessage('給線程發(fā)消息')
  this.worker.onmessage = (event) => {
    console.log('接收到的消息為:' + event.data)
  } 
}

worker 的更多API可以查看Worker MDN

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末魏滚,一起剝皮案震驚了整個濱河市镀首,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鼠次,老刑警劉巖更哄,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腥寇,居然都是意外死亡成翩,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門赦役,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麻敌,“玉大人,你說我怎么就攤上這事掂摔∈醺幔” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵乙漓,是天一觀的道長级历。 經(jīng)常有香客問我,道長叭披,這世上最難降的妖魔是什么寥殖? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮涩蜘,結(jié)果婚禮上扛禽,老公的妹妹穿的比我還像新娘。我一直安慰自己皱坛,他們只是感情好编曼,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著剩辟,像睡著了一般掐场。 火紅的嫁衣襯著肌膚如雪往扔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天熊户,我揣著相機與錄音萍膛,去河邊找鬼。 笑死嚷堡,一個胖子當(dāng)著我的面吹牛蝗罗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝌戒,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼串塑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了北苟?” 一聲冷哼從身側(cè)響起桩匪,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎友鼻,沒想到半個月后傻昙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡彩扔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年妆档,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虫碉。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡过吻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔗衡,到底是詐尸還是另有隱情纤虽,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布绞惦,位于F島的核電站逼纸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏济蝉。R本人自食惡果不足惜杰刽,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望王滤。 院中可真熱鬧贺嫂,春花似錦、人聲如沸雁乡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踱稍。三九已至曲饱,卻和暖如春悠抹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扩淀。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工楔敌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驻谆。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓卵凑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胜臊。 傳聞我的和親對象是個殘疾皇子勺卢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容