предисловие
В предыдущей статье@TDGardenСказал: "Сейчас время весеннего цветения и все восстанавливается. Все так заняты влюблённостью, что у них нет времени писать блоги".
Потом я прислал картинку мне в группу:
Итак, я понял. Мне пора вести блог. В конце концов, мы единственные, у кого есть время вести блог на фронтенде.
Что ж, не будем нести чушь, а перейдем к делу и поговорим о Event Loop. Эта статья является подведением итогов и подведением итогов изучения Event Loop за последние несколько дней.Она ссылается на статьи многих больших парней.Если есть какие-то ошибки,поправьте меня.
из одной нити
Как мы все знаем, js — это однопоточный язык. Почему однопоточный? Я цитирую плохую улицу: допустим, у js есть два потока одновременно, один поток хочет добавить контент в узел dom, а другой поток хочет удалить этот узел, какой из них должен превалировать? Конечно, решение многопоточности и многопоточности заключается в добавлении блокировок, но в этом случае будут привнесены такие проблемы, как блокировки и синхронизация состояний.
js — это язык сценариев для браузера. Его основная цель — взаимодействие с пользователями и работа с моделью DOM. Многопоточность вызовет сложные проблемы с синхронизацией.
Ну тогда однопоточная. Однако один поток приносит проблему одного потока. Существует только один поток, и задачи должны быть поставлены в очередь для выполнения. Если время выполнения предыдущей задачи очень велико (ajax запрашивает фоновые данные), последующие задачи должны ждать .
Появился Event Loop, чтобы взять на себя вину за один поток.
Event Loop
Прежде чем смотреть вниз, вы должны знать основные понятия стека, очереди, синхронной задачи, асинхронной задачи и стека выполнения.
По стеку выполнения есть очень подробная статья-рекомендация:Углубленный стек контекста выполнения JavaScript
Пожалуйста, посмотрите на изображение ниже:
-
Когда js выполняет код, код сначала попадает в стек выполнения, и код может содержать некоторые синхронные задачи и асинхронные задачи.
-
Задача синхронизации выполняется немедленно, и после выполнения стек извлекается.
-
Асинхронные задачи также распространены
ajaxпросить,setTimeoutПодождите, когда код вызывает эти API, WebAPI обрабатывают эти проблемы, и стек выполнения продолжает выполняться. -
Когда асинхронная задача имеет текущий результат (когда
ajaxКогда результат запроса возвращается), WebAPI помещает соответствующую функцию обратного вызова в очередь задач. -
Когда стек выполнения пуст, прочитайте первую функцию в очереди задач и поместите ее в стек выполнения.
Постоянно повторяется шаг 5. Когда стек выполнения пуст, система переходит к очереди задач и помещает первую функцию в стек для продолжения выполнения. Этот процесс повторяется непрерывно, что является циклом событий (Event Loop).
Давайте посмотрим на простую демонстрацию.
console.log(1);
setTimeout(() => {
console.log(2);
}, 2000);
console.log(3);
-
console.log(1)Задача синхронизации, выход 1 -
setTimeoutАсинхронные задачи передаются в webapis для обработки.Через 2 с,console.log(2)войти в очередь задач -
console.log(3)Задача синхронизации, выход 3 - Стек выполнения пуст, система считывает события в очереди задач
- воплощать в жизнь
console,log(2), выход 2
Макрозадачи и микрозадачи
Конечно, это еще не конец. Я считаю, что вы, должно быть, виделиprocess.nextTick,promiseЧто ж, в этот раз порядок выполнения будет немного сложным, посмотрите вниз.
Микрозадачи, макрозадачи и цикл событийЯ использовал очень распространенный пример, чтобы рассказать о разнице между макрозадачами и микрозадачами, поэтому я не буду здесь вдаваться в подробности. Неважно, если вы не хотите знать, потому что общих макрозадач и микрозадач всего несколько, просто запомните их.
- Общие задачи макроса:
script(整体代码),setTimeout,setInterval,I/O,setImmedidate - Общие микрозадачи:
process.nextTick,MutationObserver,Promise.then catch finally
process.nextTickа такжеsetImmidateОн поддерживает только среду Node.
а также,process.nextTickСуществует операция вставки в очередь, то есть, когда он входит в очередь микрозадач, онprocess.nextTickвпереди другие микрозадачи.
Таким образом, упомянутая выше очередь задач включает в себя очередь макрозадач и очередь микрозадач. Каждый раз, когда стек выполнения пуст, система сначала обрабатывает очередь микрозадач, обрабатывает все задачи в очереди микрозадач, а затем обрабатывает макрозадачу.
ответь на два вопроса
Я так много говорил раньше, давайте попробуем воду с двумя вопросами ниже.
new Promise(resolve => {
resolve(1);
Promise.resolve().then(() => console.log(2));
console.log(4);
}).then(t => console.log(t));
console.log(3);
hahahhhhh Я переехал вопрос Учителя Руана.
- первый
new Promiseвоплощать в жизнь,resolve(1)Указывает, что состояние созданного объекта обещания становится разрешенным. -
Promise.resolve()Это эквивалентно созданию объекта обещания, после чего анонимная функция обратного вызова входит в очередь микрозадач.[() => console.log(2)] - выход 4
-
new PromiseАнонимный обратный вызов в функции then входит в очередь микрозадач, а очередь микрозадач в это время[() => console.log(2), t => console.log(t)] - выход 3
Итак, окончательная выходная последовательность 4 3 2 1.
эммммммм, если вы не понимаете, то я думаю, вы можете сначала просмотреть егоpromise.
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
console.log('async2');
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
process.nextTick(() => {
console.log('nextTick');
})
console.log('script end');
Это дерьмовый вопрос интервью. . Я не верю, что ты этого не видел. Не мудрствуя лукаво, давайте разберем эммммм Предлагаю сначала сделать это самому, а потом уже смотреть вниз.
Видетьasync/awaitНе нервничайте, это просто синтаксический сахар.asyncУказывает, что в функции есть асинхронная операция,awaitКак выполнить предыдущий код как выполнить,awaitВыражение справа выполняется как обычно, а следующий код заблокирован, ожидаяawaitвозвращение. вернуть истинуpromiseобъект, выполните следующий код; вернитеpromiseобъект и т.д.promiseобъектresolvedвыполнить снова.
Таким образом, можно понять, что код позади размещенpromise.thenв.
- выход
script start - WebAPI помещаются после 0 с (о, самое короткое, кажется, 4 мс)
setTimeoutАнонимная функция обратного вызова внутри выбрасывается в очередь задач макроса, сокращенно['setTimeout'](Помните, что в очередь задач выбрасывается callback-функция, функция!) - выход
async1 start - выход
async2 - выводить
async1 endМикрокод кидается в очередь задач, затем очередь задач для микро['async1 end'] - выход
promise1 -
promiseСостояние объекта становитсяresolved -
promise.thenАнонимная функция входит в очередь микрозадач, и очередь микрозадач в это время['async1 end', 'promise2'] -
nextTickСократите очередь до головы очереди микрозадач,['nextTick', 'async1 end', 'promise2'] - выход
script end - Стек выполнения пуст
- выход
nextTick - выход
async1 end - выход
promise2 - Очередь микрозадач пуста
- выход
setTimeout
Эпилог
Если вы все еще не поняли после прочтения этой статьи, то я предлагаю вам прочитать еще несколько статей.Если одного печенья мало, десяти почти достаточно.
относится кpromise,async/await,NodeВ этой статье подробно не обсуждается разница между циклом событий и средой браузера, но эти знания помогут вам лучше понять цикл событий.
прочитай этоpromiseВы можете проверить воду, ответив на следующие вопросы:Eventloop — это не страшно, страшно встретить Promise.