Вы когда-нибудь задумывались, как JavaScript обрабатывает асинхронную логику? Вот тут-то и появляется цикл обработки событий. Это фундаментальная концепция JavaScript, которая используется для одновременного выполнения асинхронных задач и событий, что может повысить производительность вашего кода. Он состоит из двух очередей, одна из которых называется очередью обратного вызова, а другая называется очередью микрозадач и также известна как очередь заданий.
1. Очередь обратного вызова
Цикл событий работает путем непрерывного прослушивания событий и задач, добавленных в очередь обратного вызова механизмом JavaScript или другими API-интерфейсами, такими как пользовательский ввод и функции обратного вызова. Затем он передает их в том же порядке, в котором они были добавлены в стек вызовов, для выполнения по одному. Здесь важно отметить одну важную вещь: он передает задачу только в том случае, если стек вызовов пуст, что позволяет выполнять задачи в правильном порядке и не прерывает выполнение текущей задачи.
Например, взгляните на этот фрагмент кода ниже.
function funcA() { console.log("funcA finished"); } // this function will take approximately 12 seconds to finish function funcB() { for (let i = 0; i < 1e10; i++) {} console.log("funcB finished"); } setTimeout(funcA, 500); funcB(); clearTimeout(funcA); // Output: // funcB finished // funcA finished
В этом примере выполнение `funcA` было запланировано после 500-миллисекундной задержки с использованием setTimeout, а `funcB` было выполнено сразу после этого.
Из-за длительного времени выполнения `funcB` для завершения выполнения потребовалось 12 секунд. `funcA`, который должен быть запущен через 500 миллисекунд, будет вызываться сразу после `funcB`. Заставить `funcA`ждать 12 секунд перед выводом сообщения журнала, чтобы не мешать выполнению `funcB`.
2. Очередь микрозадач
С другой стороны, очередь микрозадач — это очередь задач, выполнение которых запланировано как можно скорее. Впервые он был реализован в движке JavaScript V8, на котором работают Google Chrome и другие современные веб-браузеры, а затем представлен в стандарте HTML в 2014 году как часть спецификации HTML5.
Аналогично очереди обратного вызова. Он используется для обработки асинхронных действий в определенном порядке, который не прерывает задачу в середине выполнения. Однако между этими двумя очередями есть несколько ключевых различий.
Прежде всего, очередь микрозадач имеет более высокий приоритет, чем очередь обратного вызова, что означает, что поставленные в очередь задачи в очереди микрозадач всегда выполняются перед задачами в очереди обратного вызова. Причина этого заключается в том, чтобы применить изменения до выполнения задач макета, что обеспечивает правильное отображение обновленного содержимого.
Во-вторых, очередь микрозадач состоит из небольших задач, часто называемых небольшими единицами работы, которые обычно являются функциями обратного вызова, связанными с обещанием или наблюдателем мутаций.
Взгляните на этот код ниже, чтобы увидеть разницу между двумя очередями.
setTimeout(() => { console.log("this is a callback function passed to callback queue") }, 0); Promise .resolve() .then(() => console.log("this is a callback function passed to the microtask queue")) clearTimeout() // Output // this is a callback function passed to the microtask queue // this is a callback function passed to the callback queue
Как вы можете видеть здесь, функция обратного вызова внутри обработчика `then` напечатала свое сообщение журнала перед функцией обратного вызова внутри setTimeout, что доказывает, что очередь микрозадач имеет более высокий приоритет.
В заключение, JavaScript использует цикл событий для обработки асинхронного выполнения, и это важно знать, потому что это может помочь вам избежать распространенных ошибок, таких как блокировка основного потока, которая может привести к сбою или замедлению вашего кода.