Synchronisch en asynchroon
invoering
Terwijl webapplicaties zich blijven ontwikkelen, ontwikkelt en evolueert JavaScript, als veelgebruikte programmeertaal, ook voortdurend. Bij web front-end-ontwikkeling wordt JavaScript voornamelijk gebruikt voor browser-UI-verwerking. UI-ontwikkeling is een typisch single-threaded, gebeurtenisgestuurd model, dus JavaScript heeft ook een programmeerparadigma gevormd met asynchrone verwerking als het belangrijkste programmeerparadigma. Bij grootschalige en complexe toepassingen worden de problemen en complexiteit veroorzaakt door asynchrone programmering echter steeds duidelijker.
De opkomst van Node.js brengt een nieuw asynchroon programmeerparadigma naar JavaScript: gebeurtenislussen en callback-functies. Dit programmeerparadigma is efficiënt en beknopt, en is geschikt voor scenario's met hoge gelijktijdigheid en I/O-intensieve scenario's. Dit programmeerparadigma brengt echter ook zijn eigen problemen en complexiteiten met zich mee. Vooral in grootschalige en complexe toepassingen moeten programmeurs omgaan met het probleem van het nesten van veel callback-functies en moeten ze omgaan met het probleem van de asynchrone oproepvolgorde, waardoor de complexiteit toeneemt. en moeilijkheidsgraad van het programma.
Om deze problemen en moeilijkheden op te lossen, ontstonden fibjs. fibjs is een ontwikkelingsframework voor applicatieservers dat voornamelijk is ontworpen voor web-back-end-ontwikkeling. Het is gebaseerd op de Google v8 JavaScript-engine en kiest een andere gelijktijdigheidsoplossing dan de traditionele callback. fibjs gebruikt glasvezel om de bedrijfscomplexiteit te isoleren die wordt veroorzaakt door asynchrone oproepen op de raamwerklaag, waardoor de moeilijkheidsgraad van de ontwikkeling aanzienlijk wordt verminderd en de prestatieproblemen die worden veroorzaakt door frequente asynchrone verwerking in de gebruikersruimte worden verminderd. Tegelijkertijd heeft het synchrone programmeerparadigma, vergeleken met het traditionele asynchrone programmeerparadigma, de voordelen van meer leesbaarheid, eenvoudige logica en eenvoudig onderhoud.
In de volgende inhoud introduceren we de voordelen en kenmerken van fibjs, en leggen we aan de hand van voorbeelden uit hoe we de synchrone en asynchrone programmeeroplossingen kunnen gebruiken.
introductie van vezels
fibjs is een krachtig JavaScript-serverframework gebaseerd op de v8-engine, voornamelijk voor web-back-end-ontwikkeling. Het is gestart in 2009 en kent al een hoge stabiliteit en productiviteit, en beschikt over een breed scala aan toepassingsmogelijkheden in binnen- en buitenland.
In fibjs wordt glasvezel gebruikt om het probleem tussen bedrijfslogica en I/O-verwerking op te lossen. Vezel verschilt van traditionele concepten zoals draden, coroutines en processen: het is een lichtgewicht draad op gebruikersniveau die kan worden beschouwd als een coöperatief multitasking-mechanisme. Glasvezel kan bedrijfslogica en I/O-bewerkingen in verschillende contexten uitvoeren en bronnen intern beheren via pre-allocatie en recycling. Vergeleken met traditionele threads en processen is het lichter, flexibeler en efficiënter.
Vergeleken met andere threadbibliotheken (zoals pthread, WinThread, Boost.Thread, enz.) heeft glasvezel de volgende voordelen:
Collaboratieve planning : Fiber is een samenwerkingsplanning die geen preventieve planning door de kernel of het besturingssysteem vereist. Het vermindert frequente contextwisselingen, versnelt de loopsnelheid van het programma en vermijdt concurrentieomstandigheden en impasseproblemen tussen threads.
Lichtgewicht : elke vezel neemt slechts een kleine stapelruimte in beslag, en een groot aantal vezels kan worden gemaakt in multi-concurrent toepassingen zonder het probleem te veroorzaken dat er te veel geheugen in beslag wordt genomen.
Efficiëntie : glasvezel wordt geïmplementeerd op basis van de kenmerken van de JavaScript-taal zelf en maakt volledig gebruik van de superieure prestaties van de v8-engine, die sneller is dan traditionele threadbibliotheken.
Door gebruik te maken van glasvezel kunnen fibjs bedrijfslogica en I/O-verwerking scheiden, waardoor asynchrone oproepen worden ingekapseld in de vorm van synchrone oproepen, waardoor het schrijven en onderhouden van code eenvoudiger en gemakkelijker te lezen wordt, en tegelijkertijd de voordelen van de JavaScript-taal.
Synchronisch programmeren in fibjs
Bij asynchrone programmering kan het nesten van callback-functies leiden tot een slechte leesbaarheid van de code, gemakkelijk het probleem van de callback-hel veroorzaken en de moeilijkheidsgraad van de code en de kosten van het debuggen verhogen. Het synchrone programmeerparadigma sluit beter aan bij menselijke denkpatronen, waardoor de codestructuur duidelijker, gemakkelijker te lezen en gemakkelijker te onderhouden is, wat de ontwikkelingsefficiëntie en codekwaliteit aanzienlijk kan verbeteren.
In fibjs is synchroon programmeren een zeer populair en veelgebruikt programmeerparadigma, dat de structuur en logica van de code intuïtiever, gemakkelijker te begrijpen en te onderhouden maakt. Sommige synchrone programmeerfuncties en modules worden in hoge mate ondersteund in fibjs, zoals util.sync, fs.readSync, enz.
In fibjs kunt u asynchrone functies van ingebouwde objecten rechtstreeks op een synchrone manier aanroepen:
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
U kunt de asynchrone functie ook omsluiten via util.sync en try...catch, zodat de glasvezel de retourwaarde van de asynchrone oproep kan verkrijgen, waardoor het synchronisatie-effect wordt bereikt, bijvoorbeeld:
1
2
3
4
5
6
7
8
9
10
11
12
13// load module
const coroutine = require("coroutine");
const util = require("util");
const fs = require("fs");
// use util.sync to wrap fs.readFile
function readFile(path) {
return util.sync(fs.readFile)(path);
}
// call the sync function
const data = readFile("myfile.txt");
console.log(data);
In het bovenstaande voorbeeld hebben we een functie met de naam readFile gedefinieerd en util.sync gebruikt om de asynchrone functie fs.readFile in te kapselen in een synchrone functie. Deze functie kan gegevens rechtstreeks retourneren via synchrone aanroepen. Deze synchrone aanroepmethode is vergelijkbaar met het traditionele JavaScript-programmeerparadigma. Het verschil is dat bij fibjs de thread niet wordt geblokkeerd, maar dat het asynchrone effect wordt bereikt via glasvezel.
Hoe util.sync werkt
util.sync is een efficiënte wrapperfunctie van de kernel. De volgende JavaScript-code kan vergelijkbare functies bereiken:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const coroutine = require("coroutine");
function sync(func) {
return function _warp() {
var ev = new coroutine.Event();
var e, r;
func.apply(this, [
...arguments,
function (err, result) {
e = err;
r = result;
ev.set();
}
]);
ev.wait();
if (e)
throw e;
return r;
}
}
Deze code definieert een toolfunctiesynchronisatie voor het omzetten van een asynchrone callback-functie in een synchrone aanroepfunctie. Het ontvangt een functie func en retourneert een nieuwe functie _wrap. Deze nieuwe functie implementeert de functie van het omzetten van de originele functie in een synchrone oproep. In de _wrap-functie wordt eerst een nieuw Event-object ev gemaakt voor threadplanning en wachten op asynchrone callback-resultaten. Gebruik vervolgens de methode apply om de oorspronkelijke functie func aan te roepen met de opgegeven parameters en een nieuwe callback-functie als parameters. Tijdens het aanroepproces vindt een asynchrone callback plaats, en de nieuwe callback-functie slaat de geretourneerde resultaten op in de variabelen e en r, en activeert het Event-object. Ten slotte wordt op basis van de variabele e besloten of er een uitzondering moet worden gegenereerd of dat de variabele r moet worden geretourneerd. Deze functie implementeert een oplossing voor het omzetten van asynchrone callback-functies in synchrone oproepen, wat de leesbaarheid en onderhoudbaarheid van de functie kan verbeteren.
Asynchrone programmering in fibjs
In fibjs kunnen de meeste asynchrone methoden (inclusief I/O- en netwerkverzoekmethoden, enz.) zowel synchrone als asynchrone oproepen ondersteunen, waardoor ontwikkelaars op elk moment kunnen kiezen welke methode ze willen gebruiken op basis van hun programmeerbehoeften.
Als we fs.readFile() als voorbeeld nemen, kunnen we deze methode op twee manieren gebruiken:
Asynchrone methode: Verwerk het resultaat van het lezen van het bestand door een callback-functie door te geven, bijvoorbeeld:
1
2
3
4
5
6const fs = require("fs");
fs.readFile("/path/to/file", (err, data) => {
if (err) throw err;
console.log(data);
});
Deze methode is geschikt voor situaties waarin u enkele bewerkingen moet uitvoeren nadat u het bestand hebt gelezen.
Synchrone methode: haal de inhoud van het bestand op door geen callback-functie door te geven, bijvoorbeeld:
1
2
3
4const fs = require("fs");
const data = fs.readFile("/path/to/file");
console.log(data);
In dit voorbeeld verkrijgen we de inhoud van het bestand door de retourwaardegegevens van het bestand te lezen. U hoeft niet te wachten tot de callback-functie het lezen van het bestand heeft voltooid voordat u doorgaat met de bewerking. Deze methode is geschikt voor situaties waarin u enkele bewerkingen moet uitvoeren voordat het lezen van het bestand is voltooid.
Het is duidelijk dat deze functie van ondersteuning van zowel synchrone als asynchrone oproepen ontwikkelaars in staat stelt verschillende methoden te gebruiken, afhankelijk van hun eigen behoeften en ontwikkelingsscenario's. In sommige gevallen is synchrone code beter leesbaar en gemakkelijker te onderhouden en te debuggen; terwijl in sommige gevallen asynchrone code de reactiesnelheid en prestaties van de code beter kan verbeteren.
U moet echter voorzichtig zijn bij het gebruik van de synchronisatiemethode. In sommige scenario's kan deze methode de huidige glasvezel blokkeren. Daarom moeten we de juiste programmeermethode kiezen op basis van de werkelijke behoeften.
ten slotte
In dit artikel introduceren we de synchrone programmeerstijl en asynchrone programmeeroplossingen van fibjs, evenals hun voordelen en toepassingsscenario's. We hebben gezegd dat fibjs de operationele complexiteit kunnen verminderen en de efficiëntie van codeontwikkeling kunnen verbeteren door glasvezel te gebruiken om bedrijfslogica en prestatieproblemen veroorzaakt door asynchrone verwerking te isoleren. Tegelijkertijd benadrukten we ook de voordelen van fibjs op het gebied van I/O-verwerking en geheugenbeheer, wat veel gemak biedt bij ontwikkeling, testen en onderhoud.
Ten slotte moedigen we lezers aan om fibjs diepgaand te verkennen en deel te nemen aan fibjs-bijdragen en gemeenschapsactiviteiten. Wij geloven dat fibjs de aandacht en steun van de open source-gemeenschap zal blijven trekken met zijn krachtige prestaties en gebruiksgemak.