JavaScript-programmeurs zijn gewend parallellisme te vervalsen, maar er is een manier om echt parallellisme te bereiken dat je nu zou moeten gebruiken.
JavaScript kan moeite hebben met prestatie-intensieve taken omdat het een single-threaded taal is. Door parallellisme te gebruiken, kunt u multithreaded uitvoering in JavaScript bereiken en de prestaties en het reactievermogen van uw moderne web-apps verbeteren.
Parallellisme in JavaScript-programmering
Parallellisme is cruciaal in moderne computers voor het verbeteren van de prestaties en schaalbaarheid. Het doet dit door effectief gebruik te maken van de beschikbare middelen.
Een veelgebruikte techniek die wordt gebruikt om parallellisme bij het programmeren te bereiken, is multi-threading. De JavaScript-thread is echter een systeem met één thread en kan slechts één taak tegelijk aan. Dit betekent dat het niet bekend is met parallelle programma-uitvoeringen.
JavaScript vervalst parallelle programmering
Een veel voorkomende misvatting over parallellisme is dat je dit kunt bereiken met behulp van
asynchrone programmeertechnieken zoals async/wait, callbacks en beloftes:// Async/wait-functie die een netwerkverzoek simuleert
asynchroonfunctiegegevens ophalen() {
const reactie = wachten ophalen();
const gegevens = wachten reactie.json();
opbrengst gegevens;
}// Callback-functie die de opgehaalde gegevens naar de console logt
functielogData(gegevens) {
troosten.log (gegevens);
}// Promise.all() methode die meerdere beloften parallel uitvoert
Belofte.alle([
gegevens ophalen(),
gegevens ophalen(),
]).Dan((resultaten) => {
troosten.log (resultaten);
});
// Roep de fetchData-functie aan en geef de logData-functie door als een callback
fetchData().dan (logData);
Deze technieken voeren eigenlijk geen code parallel uit. JavaScript gebruikt de gebeurtenislus om parallelle programmering na te bootsen binnen het ontwerp met één thread.
De gebeurtenislus is een fundamenteel onderdeel van de JavaScript-runtime-omgeving. Hiermee kunt u asynchrone bewerkingen, zoals netwerkverzoeken, op de achtergrond uitvoeren zonder de hoofdthread te blokkeren.
De gebeurtenislus controleert constant op nieuwe gebeurtenissen of taken in een wachtrij en voert ze één voor één opeenvolgend uit. Met deze techniek kan JavaScript concurrency en theoretisch parallellisme bereiken.
Gelijktijdigheid versus parallelliteit
Concurrency en parallellisme worden vaak verkeerd begrepen en verwisseld in de JavaScript-wereld.
Gelijktijdigheid in JavaScript verwijst naar de mogelijkheid om meerdere taken uit te voeren door de uitvoering van de taken te overlappen. Waar de ene taak kan beginnen voordat de andere is voltooid, maar de taken kunnen niet tegelijkertijd beginnen of eindigen. Hierdoor kan JavaScript operaties efficiënt afhandelen, zoals het ophalen van gegevens uit een REST API of bestanden lezen, zonder de hoofduitvoeringsthread te blokkeren.
Parallellisme daarentegen verwijst naar de mogelijkheid om meerdere taken tegelijkertijd over meerdere threads uit te voeren. Deze achtergrondthreads kunnen onafhankelijk en gelijktijdig taken uitvoeren. Dit opent mogelijkheden voor het bereiken van echte parallelliteit in JavaScript-toepassingen.
De toepassingen van JavaScript kunnen echte parallelliteit bereiken door middel van het gebruik van webwerkers.
Webwerkers introduceren parallelliteit met JavaScript
Web Workers zijn een kenmerk van moderne webbrowsers waarmee JavaScript-code in achtergrondthreads kan worden uitgevoerd, los van de hoofduitvoeringsthread. In tegenstelling tot de hoofdthread, die gebruikersinteracties en UI-updates afhandelt. De Web Worker zou toegewijd zijn aan het uitvoeren van rekenintensieve taken.
Hieronder is een schematische weergave van de werking van een Web Worker in JavaScript.
De rode draad en de Web Worker kunnen communiceren door middel van het doorgeven van berichten. De... gebruiken bericht plaatsen methode om berichten te verzenden en de onbericht gebeurtenishandler om berichten te ontvangen, kunt u instructies of gegevens heen en weer doorgeven.
Een webwerker maken
Om een Web Worker te maken, moet u een apart JavaScript-bestand maken.
Hier is een voorbeeld:
// main.js// Maak een nieuwe Web Worker
const arbeider = nieuw werknemer('werker.js');
// Stuur een bericht naar de Web Worker
werker.postMessage('Hallo uit de hoofdthread!');
// Luister naar berichten van de Web Worker
werknemer.onmessage = functie(evenement) {
troosten.log('Bericht ontvangen van Web Worker:', evenement.gegevens);
};
In het bovenstaande voorbeeld wordt een nieuwe Web Worker gemaakt door het pad naar het worker-script door te geven (werker.js) als argument voor de werknemer constructeur. U kunt een bericht naar de Web Worker sturen met behulp van de bericht plaatsen methode en luister naar berichten van de Web Worker met behulp van de onbericht gebeurtenishandler.
Vervolgens moet u het werkscript maken (werker.js) bestand:
// werker.js
// Luister naar berichten van de hoofdthread
self.onbericht = functie(evenement) {
troosten.log('Ontvangen bericht uit hoofdthread:', evenement.gegevens);
// Stuur een bericht terug naar de hoofdthread
zelf.postMessage("Hallo van worker.js!");
};
Het Web Worker-script luistert naar berichten van de hoofdthread met behulp van de onbericht gebeurtenishandler. Bij ontvangst van een bericht logt u het bericht binnenin uit gebeurtenis.gegevens en stuur een nieuw bericht naar de hoofdthread met de bericht plaatsen methode.
Gebruikmaken van parallellisme met webwerkers
De primaire use-case voor Web Workers is het parallel uitvoeren van rekenintensieve JavaScript-taken. Door deze taken over te dragen aan Web Workers, kunt u aanzienlijke prestatieverbeteringen bereiken.
Hier is een voorbeeld van het gebruik van een webwerker om een zware berekening uit te voeren:
// main.jsconst arbeider = nieuw werknemer('werker.js');
// Stuur gegevens naar de Web Worker voor berekening
werker.postMessage([1, 2, 3, 4, 5]);
// Luister naar het resultaat van de Web Worker
werknemer.onmessage = functie(evenement) {
const resultaat = gebeurtenis.gegevens;
troosten.log('Rekenresultaat:', resultaat);
};
Worker.js:
// Luister naar gegevens van de hoofdthread
self.onbericht = functie (evenement) {
const getallen = gebeurtenis.gegevens;const resultaat = uitvoerenHeavyCalculation (cijfers);
// Stuur het resultaat terug naar de hoofdthread
self.postMessage (resultaat);
};
functievoer HeavyCalculation uit(gegevens) {
// Voer een complexe berekening uit op de reeks getallen
opbrengst gegevens
.kaart((nummer) =>Wiskunde.pow (nummer, 3)) // Kubus elk nummer
.filter((nummer) => nummer % 20) // Filter even getallen
.verminderen((som, getal) => som + getal, 0); // Tel alle getallen bij elkaar op
}
In dit voorbeeld geeft u een reeks getallen van de hoofdthread door aan de Web Worker. De Web Worker voert de berekening uit met behulp van de verstrekte gegevensreeks en stuurt het resultaat terug naar de hoofdthread. De voerHeavyCalculation() uit functie wijst elk getal toe aan zijn kubus, filtert de even getallen eruit en telt ze uiteindelijk op.
Beperkingen en overwegingen
Hoewel Web Workers een mechanisme bieden voor het bereiken van parallellisme in JavaScript, is het belangrijk om enkele beperkingen en overwegingen in overweging te nemen:
- Geen gedeeld geheugen: Web Workers werken in afzonderlijke threads en delen geen geheugen met de hoofdthread. Ze kunnen dus niet rechtstreeks toegang krijgen tot variabelen of objecten vanuit de hoofdthread zonder dat er berichten worden doorgegeven.
- Serialisatie en deserialisatie: Bij het doorgeven van gegevens tussen de hoofdthread en Web Workers, moet u de gegevens serialiseren en deserialiseren, aangezien het doorgeven van berichten een op tekst gebaseerde communicatie is. Dit proces brengt prestatiekosten met zich mee en kan van invloed zijn op de algehele prestaties van de app.
- Browser-ondersteuning: Hoewel Web Workers goed worden ondersteund in de meeste moderne webbrowsers, bieden sommige oudere browsers of beperkte omgevingen mogelijk gedeeltelijke of geen ondersteuning voor Web Workers.
Bereik True Parallellisme in JavaScript
Parallellisme in JavaScript is een opwindend concept dat echte gelijktijdige uitvoering van taken mogelijk maakt, zelfs in een voornamelijk single-threaded taal. Met de introductie van Web Workers kunt u profiteren van de kracht van parallellisme en aanzienlijke prestatieverbeteringen in uw JavaScript-applicaties realiseren.