Introduktion till asynkron programmering

Från Webbling
Hoppa till: navigering, sök

När man skapar webbapplikationer i JavaScript, vare sig det är kod som körs på klientsidan eller på serversidan, jobbar man oftast med något som kallas asynkron programmering. Vi ska försöka reda ut vad detta innebär. Vi börjar att definiera vad ”normal”, synkron programmering är.

Synkron programmering

De flesta är nog vana med att i programmeringen så sker sakerna synkront. Det vill säga de sker i en bestämd, förutsägbar ordning. Ett programflöde där instruktion B följer tät efter instruktion A. Direkt när en har funktion körts, så kan vi använda oss av de resultat som skapades i funktionen. Det är så här de flesta programmeringsspråk fungerar, i alla fall i grunden. Varje funktionsanrop är alltså blockerande och koden kan inte gå vidare tills hela anropet är avklarat.

Ett exempel på synkron programmering skulle kunna vara följande:

	// Vi hämtar lite data ifrån en databas
	let resultat = HämtaResultat(select * from database); // Här ”stannar” körningen tills metoden är klar
	// Här fortsätter sedan programmet, när förra metoden körts klart och all data är hämtad
	BehandlaResultat(resultat);

Det här är antagligen den typ av programmering som de flesta är vana med. Vi gör klart varje grej helt och hållet innan vi går vidare med något nytt. Detta kan dock vara en dålig metodik i de fall ett av våra programmeringssteg tar mycket lång tid. Det kan vara bättre att sätta igång det som tar tid och sen bara fortsätta vidare i koden, medan det långsamma jobbar på i bakgrunden. En metod för att jobba på detta vis är asynkron programmering.

Asynkron programmering

Nu ska vi titta på asynkron programmering, något som JavaScript är bra på,. Detta handlar om att när vi kör vissa funktioner, så startas de igång, men medan de jobbar på så går vår kod vidare och kör efterföljande kod. Detta görs utan att invänta att den asynkrona metoden går klart eller att den levererar några resultat. Detta är en typ av icke-blockerande kodanrop.

Chansen är stor att den kod du startar asynkront hamnar i en egen tråd eller liknande. Det kan vara olika mekanismer som används på olika plattformar och i olika JavaScript-implementationer. Dock behöver man inte bry sig om den bakomliggande implementationen. Här ska vi bara titta på hur man programmerar med redan befintliga metoder avsedda för asynkron körning.

Språken behöver oftast ha specifikt stöd för asynkron programmering. Dels behöver vi ju något sätt på vilket vi kan ange att en metod eller kodsnutt ska köras asynkront. Men minst lika viktigt, så behöver man mekanismer som kan kolla om den metod som startats asynkront är avklarad. Det skulle ju vara oerhört ineffektivt om ens program hela tiden behövde gå in och kontrollera om den asynkrona metoden körts klart.

Callbacks

I JavaScripts-världen finns flera olika lösningar för detta, den gamla lösningen var att använda sig av "callbacks". En callback är en metod som körs när den asynkrona koden kört klart. Man skickar med denna callback-metod till det asynkrona anropet och det är upp till den att köra callbacken när den är klar. Problement med callbacks är att man ofta vill göra flera asynkrona saker på rad. Ett exempel på detta kan vara att vi öppnar en databas, skickar en förfrågan, läser in resultat. Alla dessa anrop är oftast asynkrona, vilket skulle innebära att vi skulle behöva steg efter steg av callbacks. Vilket kan bli svårläst, svåröverskådligt och svårt att underhålla.

Promises

Den "nya" metodiken för att hantera asynkrona anrop är promises. Med dessa kan man enkelt ange vad som ska ske när ett asynkront kodanrop är avklarat, vare sig det lyckats eller misslyckats. Promises brukar ofta vara rätt så lättlästa och skapa kod som inte är så mycket mer komplicerad än vad vanlig synkron kod är (något som inte alltid är fallet med andra sätt på vilket man kan hantera asynkron kod).

Ett exempel på asynkron programmering med promises kan se ut så här:

	// Vi hämtar lite data ifrån en databas

	// Den här metoden körs igång direkt, men
	// det är inte säkert att den blir klar
	// direkt
	HämtaResultat()
		// 	När HämtaResultat är klar körs detta
		.then(BehandlaResultat(resultat))
		// Om något går fel körs den här biten
		.catch(BehnadlaFel(felkod);

Ett nytt tankesätt

Att jobba med asynkron programmering innebär att man måste tänka på ett nytt sätt. Man kan inte bara skriva koden i ett enda löpande flöde och förvänta sig att saker sker en efter en. Istället måste man noggrant planera och hålla reda på vilka koddelar och data som är beroende av varandra. I början kan asynkron programmering te sig som krånglig och svår, dock brukar man bli allt mer förtjust i det desto mer asynkron kod man skriver.

Vi kommer att återkomma till asynkron programmering ofta, då det är grunden för att skapa skalbara, snabba applikationer i JavaScript. Likaså är de flesta bibliotek till JavaScript baserade kring asynkron programmering och man ”tvingas” därmed att skapa asynkrona lösningar.

Nu är du redo att gå vidare och titta på hur man bygger webbapplikationer och -tjänster.