предисловие
Всем известно, что js — это однопоточный язык сценариев, в то же время он может делать только одно и то же. появилось решение Event Loop. ...
Личный блог, чтобы узнать:obkoro1.com
Почему js однопоточный?
JS - это сценарный язык, который в основном работает в браузере. Одним из основных применений JS является манипулирование DOM.
JS проводится на возвышении каштана, если JS в то же время есть два потока одновременно на одном и том же DOM для работы, то браузер должен слушать, что поток, как определить приоритет?
Чтобы избежать этой проблемы, js должен быть однопоточным языком, и эта функция не изменится в будущем.
Стек выполнения и очередь задач
Поскольку js является однопоточным языком, при возникновении асинхронных задач (например, ajax-операций и т. д.) невозможно дождаться асинхронного завершения, а затем продолжить выполнение, в этот период браузер находится в состоянии простоя. , что, очевидно, приведет к огромной трате ресурсов.
стек выполнения
Когда функция выполняется, пользователь щелкает мышью один раз, Ajax завершается, изображение загружается и происходят другие события, пока указана функция обратного вызова, эти события будут поступать в очередь задач, когда они происходят, ожидая основного нить читать, следовать принципу "первым пришел - первым вышел".
Когда задача в очереди задач выполняется, выполняемая задача называется стеком выполнения.
основной поток
Чтобы было ясно, основной поток отличается от стека выполнения.Основной поток указывает, какое событие в стеке выполнения сейчас выполняется.
Цикл основного потока: то есть основной поток будет непрерывно считывать события из стека выполнения и выполнять все коды синхронизации в стеке.
Когда встречается асинхронное событие, оно не будет ждать, пока асинхронное событие вернет результат, а повесит событие в очередь, отличную от стека выполнения, которую мы называем очередью задач.
После того, как основной поток выполнит весь код в стеке выполнения, основной поток проверит, есть ли задачи в очереди задач.. Если они есть, то основной поток будет по очереди выполнять функции обратного вызова в этих очередях задач.
Если вы этого не понимаете, вы можете запустить следующий код или щелкнуть этотdemo
В результате после выполнения всех функций a, b и c три setTimeout будут выполняться последовательно.
let a = () => {
setTimeout(() => {
console.log('任务队列函数1')
}, 0)
for (let i = 0; i < 5000; i++) {
console.log('a的for循环')
}
console.log('a事件执行完')
}
let b = () => {
setTimeout(() => {
console.log('任务队列函数2')
}, 0)
for (let i = 0; i < 5000; i++) {
console.log('b的for循环')
}
console.log('b事件执行完')
}
let c = () => {
setTimeout(() => {
console.log('任务队列函数3')
}, 0)
for (let i = 0; i < 5000; i++) {
console.log('c的for循环')
}
console.log('c事件执行完')
}
a();
b();
c();
// 当a、b、c函数都执行完成之后,三个setTimeout才会依次执行
Работающий механизм асинхронного выполнения js.
- Все задачи выполняются в основном потоке, образуя стек выполнения.
- Помимо основного потока, существует еще «очередь задач» (task queue). Как только асинхронная задача имеет запущенный результат, событие помещается в «очередь задач».
- Как только все задачи синхронизации в «стеке выполнения» выполнены, система считывает «очередь задач». Эти соответствующие асинхронные задачи завершают состояние ожидания, входят в стек выполнения и начинают выполнение.
- Основной поток продолжает повторять третий шаг выше.
Макрозадачи и микрозадачи:
Асинхронные задачи делятся на макрозадачи и микрозадачи.Задачи, зарегистрированные с помощью разных API, будут по очереди входить в соответствующие очереди, а затем ждать, пока цикл обработки событий поместит их в стек выполнения для выполнения.
Макрозадача (macrotask)::
script (общий код), setTimeout, setInterval, рендеринг пользовательского интерфейса, ввод-вывод, postMessage, MessageChannel, setImmediate (среда Node.js)
Микрозадачи:
Promise, MutaionObserver, process.nextTick (среда Node.js)
Цикл событий:
В цикле событий каждый цикл называется тиком, и задачи каждого тика следующие:
- Стек выполнения выбирает задачу макроса, которая входит в очередь первой (обычно
script
общий код), если есть, выполнить - Проверить, есть ли микрозадача, если она существует, она будет продолжать выполняться до тех пор, пока очередь микрозадач не опустеет.
- Обновите рендеринг (каждый раз, когда происходит цикл событий, браузер может обновлять рендеринг)
- Повторите вышеуказанные шаги
Задача макроса> Все микроструктуры> Задачи макроса, как показано ниже:
Из вышеуказанного рисунка мы видим, что:
- Смотрите все задачи в качестве двух очередей: выполните очереди и очереди событий.
- Очередь выполнения синхронная, очередь событий асинхронная, макрозадача помещается в список событий, а микрозадача помещается в очередь выполнения и перед очередью событий.
- При выполнении синхронного кода выполняется микрозадача, расположенная после списка выполнения, а затем выполняется макрозадача в списке событий.
упомянутый вышеdemoРезультаты могут быть поняты: первое исполнениеscript
После выполнения задачи макроса выполняются две другие задачи макроса таймера.
попрактиковаться в вопросах интервью
Следующий вопрос, который многие люди должны были видеть/встречать, будет ли намного яснее взглянуть на него еще раз:
// 执行顺序问题,考察频率挺高的,先自己想答案**
setTimeout(function () {
console.log(1);
});
new Promise(function(resolve,reject){
console.log(2)
resolve(3)
}).then(function(val){
console.log(val);
})
console.log(4);
Согласно анализу этой статьи, мы можем получить:
-
выполнить первым
script
синхронный код先执行new Promise中的console.log(2),then后面的不执行属于微任务 然后执行console.log(4)
-
Выполнение
script
После макрозадачи выполните микрозадачу console.log(3), а других микрозадач нет. -
Выполните другую задачу макроса, таймер, console.log(1).
Судя по содержанию этой статьи, это может быть очень легко и обоснованнодогадкаНапишите правильный ответ: 2,4,3,1.
Эпилог
Вопросов на собеседовании, похожих на приведенные выше, много, но по сути они все одинаковые.Пока вы освоите механизм событийного цикла, эти вопросы станут очень простыми.
Если в статье есть какие-то неправильные места, прошу поощрить всех проходящих мимо! Я надеюсь, что вы сможете получить что-то после прочтения. Если вам это нравится, поторопитесь и нажмитеподпискаПодпишитесь/Нравится.
Друзья, которые прочитали это, могут нажать «Нравится» / «Подписаться», ваша поддержка — самая большая поддержка для меня.
личный блог and Персональная домашняя страница NuggetsЕсли вам нужно перепечатать, пожалуйста, поместите его на исходную ссылку и подпишите. Код не простой,благодарныйслужба поддержки!
Если вам понравилась эта статья, обратите внимание на мой номер подписки, долгий путь к технологиям и с нетерпением ждите совместного обучения и роста в будущем.
Выше 2018.6.16
Использованная литература:
Подробно объясните механизм цикла событий в JavaScript.
Подробное объяснение механизма работы JavaScript: снова поговорим о цикле событий