Графический механизм выполнения JS

внешний интерфейс JavaScript Promise Ajax

Грубый процесс


Мы видим, что:

  1. js код делится на синхронные задачи и асинхронные задачи.
  2. Синхронные задачи попадут в основной поток, а асинхронные задачи попадут в таблицу событий.Когда асинхронные задачи в таблице событий будут выполнены, функция обратного вызова будет зарегистрирована в очереди событий.
  3. Задачи в очереди событий будут выполнены только после завершения всех задач основного потока.
  4. Синтаксический анализатор js неоднократно проверяет, пуст ли стек выполнения основного потока, а затем повторяет шаг 3, то есть цикл обработки событий.

Типы js кода делятся на:

Уведомление

  1. Задачи можно дополнительно разделить на макрозадачи и микрозадачи, которые имеют более детальное влияние на выполнение кода js, что будет объяснено ниже в статье.
  2. Макрозадачи и микрозадачи в асинхронных задачах будут попадать в разные очереди событий очереди событий, то есть очередь событий можно разделить на очередь макрозадач и очередь микрозадач.
  3. setInterval будет повторно регистрировать функцию обратного вызова в очереди событий в соответствии с установленным интервалом времени.Если код основного потока выполняется слишком долго в течение определенного периода времени, функция обратного вызова setInterval может быть заблокирована и выполнена вместе, а набор временной интервал не может поддерживаться. setInterval используется для анимации, и это отражается как зависание.

Подробный процесс


В цикле событий (основной поток → очередь событий) на самом деле существует более подробный процесс работы, то есть цикл между (макрозадача → микрозадача), как показано на следующем рисунке:

В общем, порядок выполнения js на нашей странице такой:

  • Первый раунд цикла событий:
  1. Основной поток выполняет весь код js (макрозадачу), регистрирует функции обратного вызова, такие как ajax, setTimeout и promise, в очередь событий и различает макрозадачи и микрозадачи.
  2. Основной поток извлекает и выполняет все микрозадачи, такие как ajax и обещания, в очереди событий и регистрирует асинхронные задачи микрозадачи в очереди событий.
  • Второй раунд цикла событий:
  1. Основной поток извлекает события из очереди событий.ПервыйЗадача макроса (обычно setTimeout).
  2. Основной поток выполняет макрозадачу setTimeout и регистрирует асинхронные задачи в коде setTimeout в очереди событий (если есть).
  3. Выполните все микрозадачи в очереди событий и зарегистрируйте асинхронные задачи в микрозадачах в очереди событий (если есть).
  • Аналогичная петля:Каждый раз, когда выполняется макрозадача, микрозадача в очереди событий очищается..

Уведомление: Очередь событий разделена на "очередь макрозадач" и "очередь микрозадач". Каждый раз, когда задача выполняется, новая макрозадача или микрозадача может быть зарегистрирована в соответствующей очереди задач. Все микрозадачи в очереди событий одновременно правило циклического перебора времени, это не испортит.


пример


Пример 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');
    })
})
  • Первый раунд цикла событий:
  1. Общий сценарий входит в основной поток как первая задача макроса, сталкивается с console.log и выводит 1.

2. Когда встречается set1, его функция обратного вызова отправляется в макрозадачу Event Queue.

3. Когда встречается pro1, новое обещание выполняется напрямую и выводится 6. затем отправляется в очередь событий микрозадачи.

4. При обнаружении set2 его функция обратного вызова отправляется в макрозадачу Event Queue.

5. После выполнения всего js-кода (макроса задачи) основного потока все микрозадачи очищаются, основной поток выполняет микрозадачу pro1 и выдает 7, при встрече с set3 регистрируется callback-функция.

  • Второй раунд цикла событий:
  1. Основной поток выполняет первую макрозадачу set1 в очереди и выводит 2; когда в коде встречается set4, регистрируется обратный вызов; когда снова встречается pro2, new promise() напрямую выполняет вывод 4 и регистрирует обратный вызов;

2. После завершения выполнения макрозадачи set1 микрозадача начинает очищаться, основной поток выполняет микрозадачу pro2 и выводит 5.

  • Третий раунд цикла событий
  1. Основной поток выполняет первую макрозадачу set2 в очереди и выводит 9. Когда в коде встречается pro3, new promise() напрямую выводит 10 и регистрирует обратный вызов;
  2. После завершения выполнения макрозадачи set2 запускается микрозадача, а основной поток выполняет микрозадачу pro3 и выводит 11.
  • Похоже на петлю...

Таким образом, окончательный вывод1、6、7、2、4、5、9、10、11、8、3.