Snelle tip JavaScript-webmedewerkers verplaatsen hard werk naar de achtergrond

Een webwerker is een JS-script dat op de achtergrond wordt uitgevoerd, los van andere scripts, zodat we threading kunnen introduceren in onze web-apps. Hoewel webmedewerkers geen deel uitmaken van de HTML5-specificatie, kunnen ze worden gebruikt met HTML5-apps. In deze Snelle tip bekijken we hoe u ze kunt gebruiken.


Introductie tot webmedewerkers

In het land van HTML5 hebben we enkele zeer interessante API's beschikbaar. Sommigen van hen - zoals Web Workers - zijn nuttig voor het verbeteren van de prestaties, wat erg belangrijk is voor zowel apps als games. Maar hoe werken webmedewerkers ... nou, werk?

Elke instantie van een webwerker maakt een nieuwe thread, waarin uw JavaScript wordt uitgevoerd. Je instantiate zo als volgt:

 var worker = new Worker ('filename.js');

Hier is 'filename.js' de naam van het bestand dat uw script bevat. Omdat werknemers individuele omgevingen zijn, kunt u geen code gebruiken die rechtstreeks in HTML is ingesloten; je moet een apart bestand gebruiken.


Communicatie: gegevens verzenden en ontvangen

Werknemers hebben geen toegang tot het pagina-DOM of het globale object, dus hoe communiceren ze met de site? Het is makkelijk. Wanneer u gegevens van uw pagina naar een medewerker wilt sturen, roept u aan postMessage ().

Hiervoor is één parameter vereist: te verzenden gegevens, die een tekenreeks of een door JSON te parseren object kan zijn (wat betekent dat u geen functies of ronde-verwijzingen kunt doorgeven, anders krijgt u een DOM_EXCEPTION). In sommige browsers is er een probleem met objecten, dus het is altijd beter om het object handmatig te ontleden JSON.parse () zodat u zich geen zorgen hoeft te maken over onvolledige implementaties.

Hetzelfde geldt als u gegevens van een medewerker naar de pagina verzendt: gewoon aanroepen postMessage () op zelf, wat verwijst naar de globale reikwijdte van de werknemer. (Je doet dit natuurlijk in het werkerscript).

Vervolgens, om de gegevens te ontvangen, moet u een OnMessage gebeurtenishandler. Er zijn twee manieren om dat te doen, net als bij reguliere evenementen voor DOM-elementen; je kunt direct een functie toewijzen aan die van de Werknemer OnMessage eigendom, of je kunt gebruiken addEventListener ().

 // Eerste manier: worker.onmessage = function (e) console.log (e.data); // Log de doorgegeven gegevens in // Tweede manier: worker.addEventListener ('message', function (e) console.log (e.data); // Log de doorgegeven gegevens in);

Het is jouw keuze welke methode je moet gebruiken. Hoe dan ook, de parameter van de functie is een evenement object en de gegevens die u hebt verzonden met postMessage () zal worden doorgegeven via de gegevens eigendom van dit evenement.


Externe scripts en bibliotheken

Oké, maar wat als we een externe bibliotheek moeten gebruiken? We hebben geen toegang tot de DOM of de globale scope, dus we kunnen niet alleen het script injecteren.

Natuurlijk hoeven we dat niet te doen - daar is een functie voor. Het heet importScripts () en het accepteert een of meer argumenten: scriptnamen die binnen het bereik van de worker moeten worden geladen. Houd er rekening mee dat scripts die aan deze functie worden doorgegeven, in een willekeurige volgorde worden geladen, maar ze zullen worden uitgevoerd zoals opgegeven en de scriptuitvoering zal worden gepauzeerd totdat ze worden geladen.

 importScripts ( "one-lib.js); // Laadt één script-importScripts ('first-lib.js', 'second-lib.js', 'third-lib.js'); // Laadt drie scripts

Je kunt gebruiken importScripts overal in uw code, waardoor het eenvoudig is om JSONP-verzoeken binnen de werknemers te maken, zoals we in het volgende voorbeeld zullen doen.


Voorbeeld: werknemers in actie

Juist, dus nu wil je waarschijnlijk een werknemer in actie zien. In plaats van iets tamelijk nutteloos te laten zien, zoals het verkrijgen van prime-lenzen of Fibonacci-getallen, heb ik besloten iets te maken dat je misschien zult gebruiken na een paar wijzigingen.

Het voorbeeldscript (ik heb alleen de worker-code toegevoegd, de rest is eenvoudig te doen) krijgt de laatste 100 tweets van @envatoactive (we moeten de telling instellen op 121 in plaats van 100, omdat de Tweeter API minder tweets verzendt dan gevraagd - vraag me niet waarom, ik weet het niet).

Hier is de code die in het daadwerkelijke script voor de webwerker zou terechtkomen:

 // Helper-functie voor verwerking van de gegevens var-proces = functie (gegevens) // Itereren via de gegevens; we weten dat het een array is, dus het is veilig voor (var i = 0, v; v = data [i]; i ++) // En de tekst van tweet doorgeven aan de pagina self.postMessage (text: v.text);  // Nadat het werk klaar is, laat de pagina weten self.postMessage ("klaar");  // Attach event listener om berichten af ​​te handelen self.addEventListener ('message', function (event) // Controleer of verzonden commando 'start' // Niet nodig hier, maar kan later nuttig zijn als (event.data == "start") // Antwoord op de pagina waarop we het werk startten self.postMessage ("started"); // Kern van het script, ontvang de tweets // De callback-parameter specificeert de uit te voeren functie nadat het verzoek is gedaan // (We noemen de functie proces (), hierboven gedefinieerd.) // Telling moet 121 zijn, omdat Tweeter API een lagere hoeveelheid gegevens verzendt dan aangevraagde importScripts ("http://twitter.com/statuses/user_timeline/envatoactive. json? callback = process & count = 121 "););

Het zou gemakkelijk moeten zijn om te begrijpen hoe dit allemaal werkt vanuit de commentaren. Hiermee laadt je app alle tweets op de achtergrond, met een aparte thread.

Probeer nu de volgende equivalente code in te voegen niet gebruik webmedewerkers in plaats daarvan in de kop van een lege pagina en noteer de vertraging. (Het is nog steeds klein, maar stel je voor dat je geen 100 maar 100.000 tweets krijgt):

  

Conclusie

Zoals u kunt zien, bieden webwerkers u een eenvoudige manier om vertraging uit uw GUI te verwijderen en ingewikkelde berekeningen of netwerken te verplaatsen om threads van elkaar te scheiden.

Ik hoop dat je iets nieuws hebt geleerd van dit artikel - misschien gebruik je werknemers in je volgende project? Als u vragen of problemen heeft, kunt u hieronder reageren.