JavaScript, като език с една нишка, е изправен пред предизвикателства, когато става въпрос за обработка на отнемащи време задачи, без да се жертва отзивчивостта. За да преодолее това ограничение, JavaScript използва цикъла на събитията, критичен механизъм, който улеснява асинхронните операции. В тази публикация в блога ще изследваме работата на цикъла на събитията и неговото значение, подкрепени от примери на код, за да илюстрираме неговата магия.

Разбиране на цикъла на събития

В основата си JavaScript изпълнява код последователно, част по част, в рамките на една нишка. Това обаче създава проблем при работа с операции, които отнемат значително време, като мрежови заявки, тъй като те могат да блокират основната нишка и да направят приложението блокирано. Цикълът на събития идва на помощ чрез управление на асинхронни задачи и поддържане на неблокиращ режим на изпълнение

Цикълът на събитията е безкраен цикъл, който непрекъснато проверява опашка от съобщения за предстоящи събития. Когато се инициира асинхронна операция, като задаване на таймер с setTimeout() или извършване на AJAX заявка, тя се изпраща в цикъла на събитията и се поставя в опашката за съобщения. След това цикълът на събития обработва тези събития в определен ред, като гарантира, че основната нишка може да продължи да изпълнява друг код, докато чака асинхронните операции да завършат.

Пример 1:

console.log("Start");

setTimeout(() => {
  console.log("callback executed");
}, 200);

console.log("End");
  1. console.log("Start") се изпълнява първо и регистрира 'Старт' в конзолата.
  2. Функцията setTimeout() се извиква с функция за обратно извикване и забавяне от 2000 милисекунди (2 секунди). Тази функция не блокира, така че незабавно се връща и останалата част от кода продължава да се изпълнява.
  3. След това се изпълнява console.log("End"), като се регистрира 'End' в конзолата.
  4. След приблизително 2 секунди таймерът, зададен от setTimeout(), изтича. Функцията за обратно извикване () => { console.log("callback executed"); } се добавя към опашката за съобщения.
  5. Цикълът за събития проверява стека на повикванията и го намира празен (тъй като цялото изпълнение на синхронния код е завършено).
  6. Функцията за обратно извикване се премества от опашката на съобщенията в стека на повикванията.
  7. Функцията за обратно извикване се изпълнява, като в конзолата се записва „изпълнено обратно извикване“.

Пример 2: AJAX заявка

console.log("Start");

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.log(error));

console.log("End");
  1. console.log("Start") се изпълнява първо и регистрира 'Старт' в конзолата.
  2. Функцията fetch() се извиква, за да направи AJAX заявка към посочения URL адрес. Тази функция не блокира, така че незабавно се връща и останалата част от кода продължава да се изпълнява.
  3. След това се изпълнява console.log("End"), като в конзолата се записва 'End'.
  4. Изпълнението на AJAX заявката отнема известно време. След като отговорът бъде получен, обратното извикване then() се добавя към опашката за съобщения.
  5. Цикълът за събития проверява стека на повикванията и го намира празен (тъй като цялото изпълнение на синхронния код е завършено).
  6. Обратното извикване then() се премества от опашката за съобщения в стека за повиквания.
  7. Обратното извикване then() се изпълнява и анализираните JSON данни от отговора се записват в конзолата.

В заключение, цикълът на събитията е крайъгълен камък на асинхронното поведение на JavaScript, което позволява на езика да се справя с отнемащи време задачи. цикълът на събитията дава възможност на разработчиците да създават мащабируеми, неблокиращи и производителни приложения.