Механизм цикла событий Js (Event Loop) и объяснение примера

Node.js внешний интерфейс JavaScript Ajax
Механизм цикла событий Js (Event Loop) и объяснение примера

предисловие

Всем известно, что 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.

  1. Все задачи выполняются в основном потоке, образуя стек выполнения.
  2. Помимо основного потока, существует еще «очередь задач» (task queue). Как только асинхронная задача имеет запущенный результат, событие помещается в «очередь задач».
  3. Как только все задачи синхронизации в «стеке выполнения» выполнены, система считывает «очередь задач». Эти соответствующие асинхронные задачи завершают состояние ожидания, входят в стек выполнения и начинают выполнение.
  4. Основной поток продолжает повторять третий шаг выше.

Макрозадачи и микрозадачи:

Асинхронные задачи делятся на макрозадачи и микрозадачи.Задачи, зарегистрированные с помощью разных API, будут по очереди входить в соответствующие очереди, а затем ждать, пока цикл обработки событий поместит их в стек выполнения для выполнения.

Макрозадача (macrotask)::

script (общий код), setTimeout, setInterval, рендеринг пользовательского интерфейса, ввод-вывод, postMessage, MessageChannel, setImmediate (среда Node.js)

Микрозадачи:

Promise, MutaionObserver, process.nextTick (среда Node.js)

Цикл событий:

В цикле событий каждый цикл называется тиком, и задачи каждого тика следующие:

  • Стек выполнения выбирает задачу макроса, которая входит в очередь первой (обычноscriptобщий код), если есть, выполнить
  • Проверить, есть ли микрозадача, если она существует, она будет продолжать выполняться до тех пор, пока очередь микрозадач не опустеет.
  • Обновите рендеринг (каждый раз, когда происходит цикл событий, браузер может обновлять рендеринг)
  • Повторите вышеуказанные шаги

Задача макроса> Все микроструктуры> Задачи макроса, как показано ниже:

Из вышеуказанного рисунка мы видим, что:

  1. Смотрите все задачи в качестве двух очередей: выполните очереди и очереди событий.
  2. Очередь выполнения синхронная, очередь событий асинхронная, макрозадача помещается в список событий, а микрозадача помещается в очередь выполнения и перед очередью событий.
  3. При выполнении синхронного кода выполняется микрозадача, расположенная после списка выполнения, а затем выполняется макрозадача в списке событий.

упомянутый выше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);

Согласно анализу этой статьи, мы можем получить:

  1. выполнить первымscriptсинхронный код

     先执行new Promise中的console.log(2),then后面的不执行属于微任务
     然后执行console.log(4)
    
  2. ВыполнениеscriptПосле макрозадачи выполните микрозадачу console.log(3), а других микрозадач нет.

  3. Выполните другую задачу макроса, таймер, console.log(1).

Судя по содержанию этой статьи, это может быть очень легко и обоснованнодогадкаНапишите правильный ответ: 2,4,3,1.


Эпилог

Вопросов на собеседовании, похожих на приведенные выше, много, но по сути они все одинаковые.Пока вы освоите механизм событийного цикла, эти вопросы станут очень простыми.

Если в статье есть какие-то неправильные места, прошу поощрить всех проходящих мимо! Я надеюсь, что вы сможете получить что-то после прочтения. Если вам это нравится, поторопитесь и нажмитеподпискаПодпишитесь/Нравится.

Друзья, которые прочитали это, могут нажать «Нравится» / «Подписаться», ваша поддержка — самая большая поддержка для меня.

личный блог and Персональная домашняя страница NuggetsЕсли вам нужно перепечатать, пожалуйста, поместите его на исходную ссылку и подпишите. Код не простой,благодарныйслужба поддержки!

Если вам понравилась эта статья, обратите внимание на мой номер подписки, долгий путь к технологиям и с нетерпением ждите совместного обучения и роста в будущем.

Выше 2018.6.16

Использованная литература:

Подробно объясните механизм цикла событий в JavaScript.

Цикл событий в JavaScript

Подробное объяснение механизма работы JavaScript: снова поговорим о цикле событий