欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS多線程API?webworker應(yīng)用場(chǎng)景有哪些

 更新時(shí)間:2023年02月18日 14:15:00   作者:楊明月luna  
這篇文章主要介紹了JS多線程API?webworker應(yīng)用場(chǎng)景有哪些,加密數(shù)據(jù),預(yù)取數(shù)據(jù),預(yù)渲染,復(fù)雜數(shù)據(jù)處理場(chǎng)景,預(yù)加載圖片需要的朋友可以參考下

以前我們總說,JS是單線程沒有多線程,當(dāng)JS在頁面中運(yùn)行長(zhǎng)耗時(shí)同步任務(wù)的時(shí)候就會(huì)導(dǎo)致頁面假死影響用戶體驗(yàn),從而需要設(shè)置把任務(wù)放在任務(wù)隊(duì)列中;執(zhí)行任務(wù)隊(duì)列中的任務(wù)也并非多線程進(jìn)行的,然而現(xiàn)在HTML5提供了我們前端開發(fā)這樣的能力 - Web Workers API,我們一起來看一看 Web Worker 是什么,怎么去使用它,在實(shí)際生產(chǎn)中如何去用它來進(jìn)行產(chǎn)出。

1. 概述

Web Workers 使得一個(gè)Web應(yīng)用程序可以在與主執(zhí)行線程分離的后臺(tái)線程中運(yùn)行一個(gè)腳本操作。這樣做的好處是可以在一個(gè)單獨(dú)的線程中執(zhí)行費(fèi)時(shí)的處理任務(wù),從而允許主(通常是UI)線程運(yùn)行而不被阻塞。

它的作用就是給JS創(chuàng)造多線程運(yùn)行環(huán)境,允許主線程創(chuàng)建worker線程,分配任務(wù)給后者,主線程運(yùn)行的同時(shí)worker線程也在運(yùn)行,相互不干擾,在worker線程運(yùn)行結(jié)束后把結(jié)果返回給主線程。這樣做的好處是主線程可以把計(jì)算密集型或高延遲的任務(wù)交給worker線程執(zhí)行,這樣主線程就會(huì)變得輕松,不會(huì)被阻塞或拖慢。這并不意味著JS語言本身支持了多線程能力,而是瀏覽器作為宿主環(huán)境提供了JS一個(gè)多線程運(yùn)行的環(huán)境。

不過因?yàn)閣orker一旦新建,就會(huì)一直運(yùn)行,不會(huì)被主線程的活動(dòng)打斷,這樣有利于隨時(shí)響應(yīng)主線程的通性,但是也會(huì)造成資源的浪費(fèi),所以不應(yīng)過度使用,用完注意關(guān)閉?;蛘哒f:如果worker無實(shí)例引用,該worker空閑后立即會(huì)被關(guān)閉;如果worker實(shí)列引用不為0,該worker空閑也不會(huì)被關(guān)閉。

看一看它的兼容性

BrowserIEEdgeFireFoxChromeSafari
version10+12+3.5+4+4+

2. 使用

2.1 限制

worker線程的使用有一些注意點(diǎn)

  • 同源限制 worker線程執(zhí)行的腳本文件必須和主線程的腳本文件同源,這是當(dāng)然的了,總不能允許worker線程到別人電腦上到處讀文件吧

  • 文件限制 為了安全,worker線程無法讀取本地文件,它所加載的腳本必須來自網(wǎng)絡(luò),且需要與主線程的腳本同源

  • DOM操作限制 worker線程在與主線程的window不同的另一個(gè)全局上下文中運(yùn)行,其中無法讀取主線程所在網(wǎng)頁的DOM對(duì)象,也不能獲取 document、 window等對(duì)象,但是可以獲取 navigator、 location(只讀)、XMLHttpRequest、  setTimeout族等瀏覽器API。

  • 通信限制 worker線程與主線程不在同一個(gè)上下文,不能直接通信,需要通過 postMessage方法來通信。

  • 腳本限制 worker線程不能執(zhí)行 alert、 confirm,但可以使用 XMLHttpRequest 對(duì)象發(fā)出ajax請(qǐng)求。

2.2 web worker例子

在主線程中生成 Worker 線程很容易:

var myWorker = new Worker(jsUrl, options)

Worker()構(gòu)造函數(shù),第一個(gè)參數(shù)是腳本的網(wǎng)址(必須遵守同源政策),該參數(shù)是必需的,且只能加載 JS 腳本,否則報(bào)錯(cuò)。第二個(gè)參數(shù)是配置對(duì)象,該對(duì)象可選。它的一個(gè)作用就是指定 Worker 的名稱,用來區(qū)分多個(gè) Worker 線程。

// 主線程
var myWorker = new Worker('worker.js', {?name : 'myWorker' });

// Worker 線程
self.name // myWorker

關(guān)于api什么的,直接上例子大概就能明白了,首先是worker線程的js文件:

// workerThread1.js
let i = 1

function simpleCount() {
    i++
    self.postMessage(i)
    setTimeout(simpleCount, 1000)
}

simpleCount()

self.onmessage = ev => {
    postMessage(ev.data + ' 呵呵~')
}

在HTML文件中的body中:

Worker 輸出內(nèi)容: id='app'>

type='text' title='' id='msg'>

onclick='sendMessage()'>發(fā)送

onclick='stopWorker()'>stop!

可以自己運(yùn)行一下看看效果,上面用到了一些常用的api

主線程中的api, worker表示是 Worker 的實(shí)例:

  • worker.postMessage: 主線程往worker線程發(fā)消息,消息可以是任意類型數(shù)據(jù),包括二進(jìn)制數(shù)據(jù)

  • worker.terminate: 主線程關(guān)閉worker線程

  • worker.onmessage: 指定worker線程發(fā)消息時(shí)的回調(diào),也可以通過worker.addEventListener('message',cb)的方式

  • worker.onerror: 指定worker線程發(fā)生錯(cuò)誤時(shí)的回調(diào),也可以worker.addEventListener('error',cb)

Worker線程中全局對(duì)象為 self,代表子線程自身,這時(shí) this指向 self,其上有一些api:

  • self.postMessage: worker線程往主線程發(fā)消息,消息可以是任意類型數(shù)據(jù),包括二進(jìn)制數(shù)據(jù)

  • self.close: worker線程關(guān)閉自己

  • self.onmessage: 指定主線程發(fā)worker線程消息時(shí)的回調(diào),也可以self.addEventListener('message',cb)

  • self.onerror: 指定worker線程發(fā)生錯(cuò)誤時(shí)的回調(diào),也可以 self.addEventListener('error',cb)

注意, w.postMessage(aMessage,transferList) 方法接受兩個(gè)參數(shù), aMessage 是可以傳遞任何類型數(shù)據(jù)的,包括對(duì)象,這種通信是拷貝關(guān)系,即是傳值而不是傳址,Worker 對(duì)通信內(nèi)容的修改,不會(huì)影響到主線程。事實(shí)上,瀏覽器內(nèi)部的運(yùn)行機(jī)制是,先將通信內(nèi)容串行化,然后把串行化后的字符串發(fā)給 Worker,后者再將它還原。一個(gè)可選的 Transferable對(duì)象的數(shù)組,用于傳遞所有權(quán)。如果一個(gè)對(duì)象的所有權(quán)被轉(zhuǎn)移,在發(fā)送它的上下文中將變?yōu)椴豢捎?中止),并且只有在它被發(fā)送到的worker中可用。可轉(zhuǎn)移對(duì)象是如ArrayBuffer,MessagePort或ImageBitmap的實(shí)例對(duì)象, transferList數(shù)組中不可傳入null。

更詳細(xì)的API參見 MDN - WorkerGlobalScope。

worker線程中加載腳本的api:

importScripts('script1.js') // 加載單個(gè)腳本

importScripts('script1.js', 'script2.js') // 加載多個(gè)腳本

3. 實(shí)戰(zhàn)場(chǎng)景

個(gè)人覺得,Web Worker我們可以當(dāng)做計(jì)算器來用,需要用的時(shí)候掏出來摁一摁,不用的時(shí)候一定要收起來~

  • 加密數(shù)據(jù)

    有些加解密的算法比較復(fù)雜,或者在加解密很多數(shù)據(jù)的時(shí)候,這會(huì)非常耗費(fèi)計(jì)算資源,導(dǎo)致UI線程無響應(yīng),因此這是使用Web Worker的好時(shí)機(jī),使用Worker線程可以讓用戶更加無縫的操作UI。

  • 預(yù)取數(shù)據(jù)

    有時(shí)候?yàn)榱颂嵘龜?shù)據(jù)加載速度,可以提前使用Worker線程獲取數(shù)據(jù),因?yàn)閃orker線程是可以是用 XMLHttpRequest 的。

  • 預(yù)渲染

    在某些渲染場(chǎng)景下,比如渲染復(fù)雜的canvas的時(shí)候需要計(jì)算的效果比如反射、折射、光影、材料等,這些計(jì)算的邏輯可以使用Worker線程來執(zhí)行,也可以使用多個(gè)Worker線程,這里有個(gè)射線追蹤的示例。

  • 復(fù)雜數(shù)據(jù)處理場(chǎng)景

    某些檢索、排序、過濾、分析會(huì)非常耗費(fèi)時(shí)間,這時(shí)可以使用Web Worker來進(jìn)行,不占用主線程。

  • 預(yù)加載圖片

    有時(shí)候一個(gè)頁面有很多圖片,或者有幾個(gè)很大的圖片的時(shí)候,如果業(yè)務(wù)限制不考慮懶加載,也可以使用Web Worker來加載圖片,可以參考一下這篇文章的探索,這里簡(jiǎn)單提要一下。

// 主線程
let w = new Worker("js/workers.js");
w.onmessage = function (event) {
    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(event.data);
    document.querySelector('#result').appendChild(img)
}

// worker線程
let arr = [...好多圖片路徑];
for (let i = 0, len = arr.length; i < len; i++) {
    let req = new XMLHttpRequest();
    req.open('GET', arr[i], true);
    req.responseType = "blob";
    req.setRequestHeader("client_type", "DESKTOP_WEB");
    req.onreadystatechange = () => {
        if (req.readyState == 4) {
            postMessage(req.response);
        }
    }
    req.send(null);
}

在 Web Workers 實(shí)戰(zhàn)的時(shí)候注意:

  • 雖然使用worker線程不會(huì)占用主線程,但是啟動(dòng)worker會(huì)比較耗費(fèi)資源

  • 主線程中使用XMLHttpRequest在請(qǐng)求過程中瀏覽器另開了一個(gè)異步http請(qǐng)求線程,但是交互過程中還是要消耗主線程資源

以上就是JS多線程API webworker應(yīng)用場(chǎng)景有哪些的詳細(xì)內(nèi)容,更多關(guān)于JS多線程webworker應(yīng)用場(chǎng)景的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • a標(biāo)簽的href與onclick事件的區(qū)別詳解

    a標(biāo)簽的href與onclick事件的區(qū)別詳解

    對(duì)于a標(biāo)簽的href與onclick事件,大家都經(jīng)常見到,也經(jīng)常使用,可它們有什么區(qū)別呢?下面就讓小編來給大家詳細(xì)介紹下,感興趣的朋友可以學(xué)習(xí)下,不用謝了,哈哈
    2014-11-11
  • JavaScript的RequireJS庫入門指南

    JavaScript的RequireJS庫入門指南

    這篇文章主要介紹了JavaScript的RequireJS庫入門指南,RequireJS庫的人氣近來攀升很快,需要的朋友可以參考下
    2015-07-07
  • 詳解Bootstrap 學(xué)習(xí)(一)入門

    詳解Bootstrap 學(xué)習(xí)(一)入門

    這篇文章主要介紹了Bootstrap入門學(xué)習(xí),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 編寫Js代碼要注意的幾條規(guī)則

    編寫Js代碼要注意的幾條規(guī)則

    大家在編寫js代碼的時(shí)候需要注意的一些地方,按照下面的方法,大家就可以盡量的讓你的代碼,更優(yōu)化。
    2010-09-09
  • JavaScript中用let語句聲明作用域的用法講解

    JavaScript中用let語句聲明作用域的用法講解

    首先要注意let是ES6中的東西,起碼是IE10之前的IE瀏覽器兼容要千萬當(dāng)心!嗯...然后我們來看JavaScript中用let語句聲明作用域的用法講解
    2016-05-05
  • JavaScript中的Math.atan2()方法使用詳解

    JavaScript中的Math.atan2()方法使用詳解

    這篇文章主要介紹了JavaScript中的Math.atan2()方法使用詳解,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06
  • 淺談Javascript中深復(fù)制

    淺談Javascript中深復(fù)制

    本文主要給大家介紹了javascript中深復(fù)制的實(shí)現(xiàn)方式,這里推薦給有需要的小伙伴參考下。
    2014-12-12
  • ES6學(xué)習(xí)之變量的解構(gòu)賦值

    ES6學(xué)習(xí)之變量的解構(gòu)賦值

    有時(shí)變量多寫起來真的很麻煩,很多繁瑣的差不多的重復(fù)工作,es6為我們提供了多種更加便利的聲明變量的形式——變量的解構(gòu)賦值。下面這篇文章主要介紹了ES6中變量解構(gòu)賦值的相關(guān)資料,需要的朋友可以參考下。
    2017-02-02
  • JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡(jiǎn)單數(shù)據(jù)類型

    JavaScript高級(jí)程序設(shè)計(jì)(第3版)學(xué)習(xí)筆記3 js簡(jiǎn)單數(shù)據(jù)類型

    數(shù)據(jù)類型是編程語言的磚瓦,是所有你能想象到的復(fù)雜抽象的基礎(chǔ),在現(xiàn)代編程語言中,除了語言本身內(nèi)置的一些簡(jiǎn)單數(shù)據(jù)類型外,基本上都提供了用于自定義數(shù)據(jù)類型的語言機(jī)制(在C中也可以利用結(jié)構(gòu)體來實(shí)現(xiàn)),這些機(jī)制在一定程度上也決定了該語言的流行度和生命力
    2012-10-10
  • Javascript基礎(chǔ)回顧之(一) 類型

    Javascript基礎(chǔ)回顧之(一) 類型

    本系列所有內(nèi)容都是涉及Javascript基礎(chǔ)的,沒有時(shí)髦的玩意兒,但是我相信這些基礎(chǔ)的東西會(huì)有助于你理解那些有趣的東西的
    2017-01-01

最新評(píng)論