Поиск…
Цикл событий в веб-браузере
Подавляющее большинство современных сред JavaScript работают в соответствии с циклом событий . Это общая концепция в компьютерном программировании, которая по существу означает, что ваша программа постоянно ждет новых вещей, и когда они это делают, реагирует на них. Хост-среда вызывает вашу программу, создавая «очередь» или «галочку» или «задачу» в цикле событий, которая затем завершается . Когда этот поворот закончится, среда хоста ждет чего-то еще, прежде чем все это начнется.
Простой пример этого в браузере. Рассмотрим следующий пример:
<!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>
В этом примере среда хоста - это веб-браузер.
- Парсер HTML сначала выполнит
<script>
. Он будет завершен. - Вызов
setTimeout
сообщает браузеру, что после 100 миллисекунд он должен поставить в очередь задачу для выполнения данного действия. - В то же время цикл событий затем отвечает за постоянную проверку, есть ли что-то еще: например, отображение веб-страницы.
- После 100 миллисекунд, если цикл событий не занят по какой-либо другой причине, он увидит задачу, которую
setTimeout
завершает, и запустит эту функцию, выполнив регистрацию этих двух операторов. - В любое время, если кто-то нажимает на тело, браузер отправляет задание в цикл событий, чтобы запустить функцию обработчика кликов. Цикл событий, когда он постоянно проверяет, что делать, увидит это и запустит эту функцию.
Вы можете видеть, как в этом примере есть несколько разных типов точек входа в код JavaScript, который вызывает цикл события:
- Элемент
<script>
вызывается немедленно - Задача
setTimeout
отправляется в цикл событий и запускается один раз - Задача обработчика кликов может быть вывешена много раз и запускаться каждый раз
Каждый поворот цикла событий отвечает за многие вещи; только некоторые из них будут ссылаться на эти задачи JavaScript. Полную информацию см. В спецификации HTML
Последнее: что мы имеем в виду, говоря, что каждая задача цикла цикла «заканчивается»? Мы имеем в виду, что обычно невозможно прерывать блок кода, который поставлен в очередь для запуска в качестве задачи, и никогда не возможно запускать код, чередующийся с другим блоком кода. Например, даже если вы щелкнули в идеальное время, вы никогда не сможете заставить вышеуказанный код регистрировать "onclick"
между двумя setTimeout callback log 1/2"
s. Это связано с тем, как работает задача-проводка; является кооперативным и основанным на очереди, а не превентивным.
Асинхронные операции и цикл событий
Многие интересные операции в обычных средах программирования JavaScript являются асинхронными. Например, в браузере мы видим такие вещи, как
window.setTimeout(() => { console.log("this happens later"); }, 100);
и в Node.js мы видим такие вещи, как
fs.readFile("file.txt", (err, data) => { console.log("data"); });
Как это соотносится с циклом событий?
Как это работает, когда эти операторы выполняются, они сообщают хост-среде (т. Е. Браузеру или Node.js runtime, соответственно), чтобы уйти и что-то сделать, возможно, в другом потоке. Когда хост-среда выполняется с этой вещью (соответственно, ожидая 100 миллисекунд или просматривая файл file.txt
), она отправляет задание в цикл событий, говоря: « file.txt
обратный вызов, который я получил ранее с этими аргументами».
Цикл событий затем занят своим делом: рендерингом веб-страницы, прослушиванием пользовательского ввода и постоянным поиском размещенных задач. Когда он видит, что эти опубликованные задачи вызывают обратные вызовы, он будет переходить на JavaScript. Так вы получаете асинхронное поведение!