Sök…
Händelsslingan i en webbläsare
De allra flesta moderna JavaScript-miljöer arbetar enligt en händelseslinga . Detta är ett vanligt begrepp inom datorprogrammering som i huvudsak innebär att ditt program ständigt väntar på att nya saker ska hända, och när de gör det, reagerar på dem. Värdmiljön ringer in i ditt program och leker en "tur" eller "kryss" eller "uppgift" i händelsslingan, som sedan slutförs . När den svängen är klar väntar värdmiljön på att något annat ska hända, innan allt detta börjar.
Ett enkelt exempel på detta finns i webbläsaren. Tänk på följande exempel:
<!DOCTYPE html> <title>Event loop example</title> <script> console.log("this a script entry point"); document.body.onclick = () => { console.log("onclick"); }; setTimeout(() => { console.log("setTimeout callback log 1"); console.log("setTimeout callback log 2"); }, 100); </script>
I det här exemplet är värdmiljön webbläsaren.
- HTML-parsern kör först
<script>
. Den kommer att slutföras. - Samtalet till
setTimeout
berättar för webbläsaren att det efter 100 millisekunder bör ange en uppgift att utföra den angivna åtgärden. - Under tiden är händelsslingan sedan ansvarig för att kontinuerligt kontrollera om det finns något annat att göra: till exempel att rendera webbsidan.
- Efter 100 millisekunder, om händelsslingan inte är upptagen av någon annan anledning, kommer den att se den uppgift som
setTimeout
anger och kör funktionen och loggar de två uttalandena. - Om någon klickar på kroppen när som helst kommer webbläsaren att lägga upp en uppgift i händelsslingan för att köra klickhanteraren. Händelsslingan, när den kontinuerligt kontrollerar vad man ska göra, kommer att se detta och köra den funktionen.
Du kan se hur det i det här exemplet finns flera olika typer av inmatningspunkter i JavaScript-kod, som händelsslingan åberopar:
- Elementet
<script>
aktiveras omedelbart -
setTimeout
uppgiftensetTimeout
upp i händelsslingan och körs en gång - Klickhanteraren kan läggas upp många gånger och köras varje gång
Varje sväng i händelsslingan ansvarar för många saker; bara några av dem kommer att åberopa dessa JavaScript-uppgifter. Mer information finns i HTML-specifikationen
En sista sak: vad menar vi med att säga att varje händels loopuppgift "går till slut"? Vi menar att det generellt inte är möjligt att avbryta ett kodblock som står i kö för att köra som en uppgift, och det är aldrig möjligt att köra kod interfolierad med ett annat kodblock. Till exempel, även om du klickade på den perfekta tiden, kan du aldrig få ovanstående kod för att logga "onclick"
mellan de två setTimeout callback log 1/2"
. Detta beror på hur uppgiften publiceras; är kooperativt och köbaserat istället för förhindrande.
Asynkrona operationer och händelsslingan
Många intressanta funktioner i vanliga JavaScript-programmeringsmiljöer är asynkrona. Till exempel i webbläsaren ser vi saker som
window.setTimeout(() => { console.log("this happens later"); }, 100);
och i Node.js ser vi saker som
fs.readFile("file.txt", (err, data) => { console.log("data"); });
Hur passar detta med evenemangslingan?
Hur detta fungerar är att när dessa uttalanden körs berättar de för värdmiljön (dvs. webbläsarens respektive Node.js runtime) att gå av och göra något, antagligen i en annan tråd. När värdmiljön är klar med att göra den saken (väntande 100 millisekunder eller läsa file.txt
) kommer den att lägga upp en uppgift i händelsslingan och säga "ringa upp det återuppringning som jag fick tidigare med dessa argument".
Händelsslingan är då upptagen med att göra sina saker: att göra webbsidan, lyssna efter användarinmatning och kontinuerligt leta efter upplagda uppgifter. När den ser de upplagda uppgifterna för att ringa återuppringningar kommer den att ringa tillbaka till JavaScript. Det är så du får asynkront beteende!