Logo Light
Published on

Event loop v JavaScriptu

Program JavaScriptu běží v jednom vlákně, takže v jednu chvíli dokáže zpracovávat vždy jen jednu věc. Stále ale dokáže provádět asynchronní úlohy bez blokování ostatních úloh a to díky event loopu.

Event Loop

Celý proces se kládá z několika částí:

1. Call stack

Pro zpracování úloh (funkcí) používá JavaScrtipt zásobník (Call stack) - funkce, která byla na zásobník uložena jako poslední, se zpracuje jako první (princip LIFO – last-in, first-out).

2. Web API (popř. Node.js API) pro asynchronní úlohy

Asynchronní úlohy (jako setTimeout, fetch, DOM eventy apod.) jsou řízeny mimo Call stack pomocí Web API (popř. Node.js API). Tyto úlohy pak informují JavaScript o svém dokončení.

3. Callback queue

Ve chvíli, kdy asynchronní úloha skončí, je její výsledek (callback) umístěn do fronty (Callback queue), kde čeká na zpracování.

4. Event loop

Event loop neustále ověřuje, jestli je Call stack prázdný. Pokud je prázdný, může do něj vložit nový callback z fronty.

Jak je možné, že najednou běží synchronní i asynchronní funkce, když je JavaScript jednovláknový?

JavaScript je jednovláknový, ale prohlížeč ne! JavaScript jako takový běží v jednom vlákně a používá svůj Call stack. Ale prohlížeč (popř. Node.js) obsahují další komponenty, které běží v samostatných vláknech mimo hlavní JavaScriptové vlákno. Web API (popř. Node.js API) běží v nezávislém vlákně v prohlížeči (popř. v Node.js) - není to součást samotného JavaScriptového vlákna.

Příklad

setTimeout(() => {
  console.log("Hello!");
}, 1000);

JavaScript tu vidí asynchronní funkci setTimeout a pošle jí do Web API (popř. Node.js API). Funkce je tedy zpracovávaná prohlížečem (popř. Node.js) nikoliv samotným JavaScriptem. Po 1000ms je callback funkce (v našem případě console.log("Hello!")) umístěna do Callback queue. Event loop mezitím stále ověřuje, zda je Call stack prázdný. Když je prázdný,tak přesune callback funkci z Callback queue do Call stacku, odkud pak dojde k jejímu provedení. Takže i když Javascript sám neprovádí funkce setTimer, tak provede její callback, jakmile je připraven.