JavaScript Web Workers: A Beginner's Guide
2019-ben a webes ökoszisztéma arra a pontra fejlődött, ahol a böngésző végrehajtási környezet a JavaScriptre épülő alkalmazások számára. Ezt tükrözi az a sebesség, amellyel az ipar jön ki új keretek, paradigmák, modul rakodó, valamint bundlers, függőség vezetők, épít az eszközök csomag vezetők évről évre.
amikor a JavaScript az internet korai napjaiban született, az internetfejlesztés iránya nem volt egyértelmű. Az iparág és az ökoszisztéma folyamatos, gyors változása, a böngészők és a webes szabványok visszamenőleges kompatibilitásának szükségessége miatt a JavaScript fejlődése folyamatos Patch -, Hack-és afterthoughts-adatfolyammá vált.
a mai mobil eszközök általában 8+ CPU magot vagy 12+ GPU magot tartalmaznak. Az asztali és szerver CPU-knak legfeljebb 16 magja, 32 szála van, vagy több.
ebben a környezetben a domináns programozási vagy szkriptkörnyezet, amely egyszálú, szűk keresztmetszet.
A JavaScript egyszálú
Ez azt jelenti, hogy a tervezés során a JavaScript-motorok-eredetileg böngészők-egy fő végrehajtási szálat tartalmaznak, és egyszerűen fogalmazva, a folyamat vagy a B funkció nem hajtható végre, amíg az a folyamat vagy a funkció befejeződik. A weboldal felhasználói felülete nem reagál semmilyen más JavaScript feldolgozásra, miközben valami végrehajtásával foglalkozik-ezt DOM blokkolásnak nevezik.
ez szörnyen hatékony, különösen más nyelvekhez képest.
Ha a JS Bin-be megyünk, futtatjuk ezt a kódot a böngésző JavaScript konzoljában:
//noprotecti = 0;while (i < 60000) { console.log("The number is " + i); i++;}
… az egész jsbin.com a weboldal addig nem reagál, amíg a böngésző 60 000 — re nem számít — és nem jelentkezik be.
az oldalon nem tudunk kapcsolatba lépni semmivel, mert a böngésző foglalt.
Ez egy viszonylag igénytelen számítási folyamat, a mai webes alkalmazások gyakran sokkal igényesebb feladatokat is magukban foglalnak.
képesnek kell lennünk arra, hogy kiszámítsuk a dolgokat a háttérben, miközben a felhasználó zökkenőmentesen kölcsönhatásba lép az oldallal.
Webmunkások
a W3C 2009-ben közzétette a webmunkások szabványának első tervezetét. A teljes specifikáció megtalálható a Web Hypertext Application Technology Working Group honlapján – vagy WHATWG-a web Standard test alternatívája W3C.
Web dolgozók egy aszinkron rendszer, vagy protokoll, a weboldalak feladatok elvégzésére a háttérben, függetlenül a fő téma és weboldal UI. Ez egy elszigetelt környezet, amely a window
objektumtól, a document
objektumtól, közvetlen internet-hozzáféréstől szigetelt, és a legjobban alkalmas hosszú távú vagy igényes számítási feladatokhoz.
a webmunkások mellett-a többszálú feldolgozásra szánt rendszer-más módon is elérhetjük az aszinkron feldolgozást a JavaScriptben, például aszinkron Ajax hívásokban, valamint az eseményhurokban.
ezt bizonyítja, visszamegyünk JS Bin, majd próbálja meg ez a részlet:
console.log("A");setTimeout(function(){console.log("B");},2000);console.log("C");setTimeout(function(){console.log("D");},0);console.log("E");setTimeout(function(){console.log("F");},1000);
Amikor ezt a log sorrend A, C, E, D, F, B
. A böngésző először időtúllépés nélkül ütemezi a műveleteket, ahogy jönnek, majd végrehajtja a setTimeout()
funkciókat a megadott késések sorrendjében. Ezt az aszinkronitást azonban nem szabad automatikusan összekeverni a többszálúakkal. Attól függően, hogy a fogadó gép, ez gyakran csak egy szál köteg a hívások a sorrendben elmagyaráztuk.
Webmunkások & többszálú
ahogy a Mozilla JavaScript referencia weboldala elmagyarázza, a webmunkások a ” webes tartalom eszközei a szkriptek futtatásához háttérszálakban.”
a következő módon használjuk őket: ellenőrizzük a Worker()
konstruktor elérhetőségét a böngészőben, és ha rendelkezésre áll, akkor egy worker objektumot instantálunk, a szkript URL-jét argumentumként. Ez a szkript egy külön szálon kerül végrehajtásra.
a szkriptet biztonsági okokból ugyanabból a gazdagépből vagy tartományból kell kézbesíteni, és ez az oka annak is, hogy a webmunkások nem fognak működni, ha a fájlt helyileg megnyitjuk egyfile://
sémával.
if (typeof(Worker) !== "undefined") { worker = new Worker("worker.js");}
most definiáljuk ezt a kódot a worker.js
fájlban:
i = 0;while (i < 200000) { postMessage("Web Worker Counter: " + i); i++;}
Ha kiváló minőségű JavaScript web worker fájlokat szeretne írni, nézze meg könyvünket, JavaScript: legjobb gyakorlat.
A szálak elválasztása
fontos megjegyezni, hogy itt awindow
ésdocument
a végrehajtás hatóköre a fő böngészőablakban, valamint aworker
hatókör.
aworker
szál használatához e két hatókörnek képesnek kell lennie a kommunikációra. Ennek eléréséhez apostMessage()
függvényt használjuk aworker.js
fájlon belül — üzenetek küldéséhez a fő böngészőszálra — és aworker.onmessage
hallgató a fő szálban, hogy meghallgassuk aworker
üzeneteket.
a fő böngészőszálról is küldhetünk üzeneteket a worker
szál vagy funkció. Az egyetlen különbség az, hogy megfordítjuk a dolgokat, a fő szálon pedig a worker.postMessage()
, a onmessage
a munkaszálon. A Mozilla fejlesztői hivatkozásának idézése:
vegye figyelembe, hogy
onmessage
éspostMessage()
le kell függeszteni aWorker
objektumot, ha a fő szkriptszálban használják, de nem a dolgozóban. Ennek oka az, hogy a munkavállalón belül a munkavállaló ténylegesen a globális hatókör.
a terminate()
módszert ugyanúgy használhatjuk a munkavállaló végrehajtásának befejezéséhez.
mindezt szem előtt tartva, erre a példára jutunk:
index.html
<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>Web Workers Example</title> <style type="text/css"> body {padding-top:28px;} .output-cont {margin-left:12%; margin-top:28px;} .output-cont h3 {width:200px; height:100%;} .output-cont button {padding:4px 8px; font-size:1.1rem; font-family:sans-serif; } </style></head><body><div class="output-cont"><button onclick="testWorker()">start worker</button><h3></h3><button onclick="terminateWorker()">terminate worker</button></div><br/><div class="output-cont"><button onclick="testMainThread()">start blocking thread</button><h3></h3></div><br/><div class="output-cont"><button onclick="alert('browser responsive!')">test browser responsiveness</button></div> <script> var worker; function testWorker() { if (typeof(Worker) !== "undefined") { if (typeof(worker) == "undefined") { worker = new Worker("worker.js"); } worker.onmessage = function(event) { document.getElementById("workerOutput").innerHTML = event.data; }; } else { document.getElementById("workerOutput").innerHTML = "Web Workers are not supported in your browser"; } } function terminateWorker() { worker.terminate(); worker = undefined; } function testMainThread() { for (var i = 0; i < 200000; i++) { document.getElementById("mainThreadOutput").innerHTML = "Main Thread Counter: " + i; } } </script></body></html>
és munkás.js:
i = 0;while (i < 200000) { postMessage("Web Worker Counter: " + i); i++;}
Ez lehetőséget ad arra, hogy teszteljük a főszál végrehajtásának hatását az oldal viselkedésére és teljesítményére a webmunkás hatásaival szemben.
ebben az oktatóanyagban ahttp-server
– ot használtuk a fájlok helyi kiszolgálására.
Most azt látjuk, hogy a worker szál nem blokkolja az interaktivitás, a fő böngésző folyamat, hurok keresztül 200,000 számok nem érinti a fő szál. A #workerOutput
elem számai minden iteráción frissülnek.
A blokkoló szál, vagy a fő szál, ha részt vesz egy hurok, blokkok minden interaktivitás (sor száma ismétlések 200.000, de lesz ez még inkább nyilvánvaló, ha növeljük 2 000 000).
még egy dolog, ami egy blokkolt főszálra mutat minket, az, hogy a munkamódszer minden iteráción frissíti az oldalt, a fő szál hurokja pedig (a index.html
) csak az utolsó iteráció #mainThreadOutput
elemét frissíti.
Ez azért van, mert a böngésző túlságosan el van fogyasztva a számlálással (for
hurok), hogy képes legyen újrarajzolni a DOM-ot, tehát csak akkor teszi meg, ha a for
hurok teljesen elkészült (a hurok végén).
következtetés
ebben a cikkben bemutattuk a webmunkásokat, egy olyan technológiát, amely segít a webiparnak lépést tartani az egyre igényesebb webes alkalmazásokkal. Ezt azáltal, így web apps tőkeáttétel multi-processzor multi-menetes eszközök által ajándékozó néhány multi-menetes nagyhatalmak kell a JavaScript használatát.
A webmunkások a mobil-és asztali böngészőkörnyezeteket alkalmazásplatformokká alakítják, szigorú végrehajtási környezetet biztosítva számukra. Ez a szigorúság arra kényszeríthet bennünket, hogy gondoskodjunk az objektumok több szál közötti másolásáról, valamint alkalmazásaink megtervezéséről ezekkel a korlátokkal szem előtt tartva.