Грубый процесс
Мы видим, что:
- js код делится на синхронные задачи и асинхронные задачи.
- Синхронные задачи попадут в основной поток, а асинхронные задачи попадут в таблицу событий.Когда асинхронные задачи в таблице событий будут выполнены, функция обратного вызова будет зарегистрирована в очереди событий.
- Задачи в очереди событий будут выполнены только после завершения всех задач основного потока.
- Синтаксический анализатор js неоднократно проверяет, пуст ли стек выполнения основного потока, а затем повторяет шаг 3, то есть цикл обработки событий.
Типы js кода делятся на:
Уведомление
- Задачи можно дополнительно разделить на макрозадачи и микрозадачи, которые имеют более детальное влияние на выполнение кода js, что будет объяснено ниже в статье.
- Макрозадачи и микрозадачи в асинхронных задачах будут попадать в разные очереди событий очереди событий, то есть очередь событий можно разделить на очередь макрозадач и очередь микрозадач.
- setInterval будет повторно регистрировать функцию обратного вызова в очереди событий в соответствии с установленным интервалом времени.Если код основного потока выполняется слишком долго в течение определенного периода времени, функция обратного вызова setInterval может быть заблокирована и выполнена вместе, а набор временной интервал не может поддерживаться. setInterval используется для анимации, и это отражается как зависание.
Подробный процесс
В цикле событий (основной поток → очередь событий) на самом деле существует более подробный процесс работы, то есть цикл между (макрозадача → микрозадача), как показано на следующем рисунке:
В общем, порядок выполнения js на нашей странице такой:- Первый раунд цикла событий:
- Основной поток выполняет весь код js (макрозадачу), регистрирует функции обратного вызова, такие как ajax, setTimeout и promise, в очередь событий и различает макрозадачи и микрозадачи.
- Основной поток извлекает и выполняет все микрозадачи, такие как ajax и обещания, в очереди событий и регистрирует асинхронные задачи микрозадачи в очереди событий.
- Второй раунд цикла событий:
- Основной поток извлекает события из очереди событий.ПервыйЗадача макроса (обычно setTimeout).
- Основной поток выполняет макрозадачу setTimeout и регистрирует асинхронные задачи в коде setTimeout в очереди событий (если есть).
- Выполните все микрозадачи в очереди событий и зарегистрируйте асинхронные задачи в микрозадачах в очереди событий (если есть).
- Аналогичная петля:Каждый раз, когда выполняется макрозадача, микрозадача в очереди событий очищается..
Уведомление: Очередь событий разделена на "очередь макрозадач" и "очередь микрозадач". Каждый раз, когда задача выполняется, новая макрозадача или микрозадача может быть зарегистрирована в соответствующей очереди задач. Все микрозадачи в очереди событий одновременно правило циклического перебора времени, это не испортит.
пример
Пример 1
console.log('1');
// 1 6 7 2 4 5 9 10 11 8 3
// 记作 set1
setTimeout(function () {
console.log('2');
// set4
setTimeout(function() {
console.log('3');
});
// pro2
new Promise(function (resolve) {
console.log('4');
resolve();
}).then(function () {
console.log('5')
})
})
// 记作 pro1
new Promise(function (resolve) {
console.log('6');
resolve();
}).then(function () {
console.log('7');
// set3
setTimeout(function() {
console.log('8');
});
})
// 记作 set2
setTimeout(function () {
console.log('9');
// 记作 pro3
new Promise(function (resolve) {
console.log('10');
resolve();
}).then(function () {
console.log('11');
})
})
- Первый раунд цикла событий:
- Общий сценарий входит в основной поток как первая задача макроса, сталкивается с console.log и выводит 1.
- Второй раунд цикла событий:
- Основной поток выполняет первую макрозадачу set1 в очереди и выводит 2; когда в коде встречается set4, регистрируется обратный вызов; когда снова встречается pro2, new promise() напрямую выполняет вывод 4 и регистрирует обратный вызов;
- Третий раунд цикла событий
- Основной поток выполняет первую макрозадачу set2 в очереди и выводит 9. Когда в коде встречается pro3, new promise() напрямую выводит 10 и регистрирует обратный вызов;
- После завершения выполнения макрозадачи set2 запускается микрозадача, а основной поток выполняет микрозадачу pro3 и выводит 11.
- Похоже на петлю...
Таким образом, окончательный вывод1、6、7、2、4、5、9、10、11、8、3
.