[Перевод] Графический цикл событий

JavaScript
[Перевод] Графический цикл событий

оригинальный:Визуализация JavaScript: цикл событий — Лидия Халли
В этой статье в основном объясняются некоторые основные концепции цикла событий с помощью ярких анимаций, в основном для начинающих, и переводчик получил согласие автора оригинала. Некоторые части этой статьи перефразированы, чтобы помочь вам лучше понять.

Эта статья была впервые опубликована в моем личном блогеLogan's Blog, другой контент, связанный с JS, также можно найти в блоге младшего брата, чтобы изучить и обсудить его вместе.

Цикл событий, — это концепция, с которой столкнется каждый разработчик JS, но могут возникнуть различные сомнения, когда вы впервые столкнетесь с ней. Я визуальный ученик, поэтому я намерен помочь всем понять это с помощью визуальной формы GIF-анимации.

Сначала давайте посмотрим, что такое цикл событий и почему мы должны это понимать?

Как мы все знаем, JavaScriptоднопоточныйДа, то есть одновременно может выполняться только одна задача. Обычно это не проблема, но если мы хотим запустить задачу, которая занимает 30 секунд, нам нужно подождать 30 секунд, прежде чем мы сможем выполнить следующую задачу (в течение этих 30 секунд JavaScript занимает основной поток, и мы не можем выполнить ничего не делай, в том числе и страница тоже застревает). Прошло 9012 лет, не приведешь ли ты такого дурака?

К счастью, браузеры предоставляют нам функции, которых нет у движков JS:Web API.Web APIвключатьDOM API,定时器,HTTP请求и другие функции, которые могут помочь нам достичьАсинхронный, неблокирующийповедение.

Когда мы вызываем функцию, она помещается в файл с именемстек вызовов(стек вызовов, также называемый стеком контекста выполнения). Стек вызовов является частью движка JS, а не специфичным для браузера. Стек вызовов представляет собойструктура данных стека,имеютпоследний пришел первый вышелОсобенности (Последний пришел, первый ушел. LIFO). Когда функция завершит выполнение и вернется, она будет удалена из стека вызовов.

в легендеrespondфункция возвращаетsetTimeoutвызов функции,setTimeoutфункцияWeb APIПредоставляемая нам функциональность: Позволяет отложить выполнение задачи, не блокируя основной поток.setTimeoutПри вызове функция обратного вызова, которую мы передаем, функция стрелки() => { return 'hey' }будет переданоWeb APIпроцесс, затемsetTimeoutа такжеrespondВ свою очередь завершает стек.

существуетWeb APIТаймер будет выполняться посередине, а временной интервал — это то, что мы передаем.setTimeoutВторой параметр, равный 1000 мс. По истечении времени таймера callback-функция не попадет сразу в стек вызовов для выполнения, а будет добавлена ​​в функцию, вызываемуюОчередь задачМесто.

Увидев это, некоторые могут задаться вопросом: через 1000 мс callback не кладется в стек вызовов на выполнение, а ставится в очередь задач, когда же он будет выполняться? Не волнуйтесь, так как это очередь, вы должны сидеть в ряд и есть фрукты.

Дальше то, чего мы так долго ждали, долгожданныйЦикл событийПришло время сиять. Задача цикла событий состоит в том, чтобы соединить очередь задач и стек вызовов.Когда задачи в стеке вызовов выполняются, а стек вызовов пуст, цикл событий проверяет, есть ли задачи, ожидающие выполнения в очереди задач, и если да то убери очередь.В первой задаче положи на стек вызовов.

Наша функция обратного вызова помещается в стек вызовов, выполняется, возвращает возвращаемое значение, а затем извлекается из стека вызовов.

Чтение – это круто какое-то время, но только до тех пор, пока вы не сделаете его своим собственным путем многократной практики. Давайте сделаем небольшое упражнение, чтобы проверить результаты обучения и посмотреть, что выводит следующий код:

const foo = () => console.log('First');
const bar = () => setTimeout(() => console.log('Second'), 500);
const baz = () => console.log('Third');

bar();
foo();
baz();

Я считаю, что каждый может легко дать правильный ответ. Давайте посмотрим, что произойдет, когда этот код запустится:

  1. barвызывается, возвращаетсяsetTimeoutвызов;
  2. входящийsetTimeoutОбратный вызов передаетсяWeb APIиметь дело с,setTimeoutПосле выполнения извлеките стек,barВыполняется и выталкивается из стека;
  3. Таймер начинает работать, пока основной потокfooназывается, печатаетFirst,fooВыполняется и выталкивается из стека;
  4. bazназывается, печатаетThird,bazВыполняется и выталкивается из стека;
  5. Через 500 мс запускается таймер и функция обратного вызова помещается в очередь задач;
  6. Цикл обработки событий обнаруживает, что стек вызовов пуст, и берет функцию обратного вызова из очереди задач и помещает ее в стек вызовов;
  7. Функция обратного вызова выполнена, выведитеSecondПосле завершения выполнения.

Я надеюсь, что эта статья поможет вам составить предварительное представление о цикле событий.Если у вас есть какие-либо сомнения, вы можете оставить сообщение для обсуждения.