Как связаны цикл событий, очередь обратного вызова и единый поток Javascript?

ОБЩАЯ ЦЕЛЬ

Я хотел бы знать, как следующие части среды javascript взаимосвязаны как система.

  • Javascript Engine
  • Цикл событий
  • Очередь событий

Мы можем ограничить это средой браузера, поскольку узел описан в другой статье (здесь)

ЧТО Я (верю) ПОНИМАЮ:

  • Javascript является однопоточным и поэтому имеет только один стек вызовов.

  • Среды Javascript предоставляют только несколько действительно асинхронных функций. Они могут включать setTimeout (), setInterval () и функции ввода-вывода.

  • Разработчик не может создавать свои собственные асинхронные функции без использования одной из них.
  • Сам Javascript работает синхронно, но через его асинхронные функции могут выполнять обратный вызов потенциально блокирующим функциям, как только текущий стек вызовов очищен.

ПРИМЕР:

      console.log(‘Sync code started…’);

      setTimeout(function asyncLog() {
           console.log(‘Async function has completed’)
      }, 2000);

      console.log(‘Sync code finished…')

ПРИМЕР ШАГИ:

(Пожалуйста, исправьте шаги, если я ошибаюсь)

  1. «Синхронизация кода запущена…» регистрируется.
  2. setTimeout добавляется в стек, но сразу возвращает управление
  3. setTimeout отправляется другому «потоку» ... «worker»? вне единственного потока javascript для подсчета 2000 миллисекунд
  4. «Синхронизация кода завершена…» регистрируется.
  5. Через 2000 миллисекунд asyncLog () помещается в очередь событий.
  6. Поскольку стек вызовов очищен, цикл событий проверяет очередь событий на наличие ожидающих обратных вызовов.
  7. asyncLog () удаляется из очереди и помещается в стек циклом событий
  8. "Асинхронная функция завершена" регистрируется
  9. стек вызовов теперь очищен

ВОПРОСОВ

На эти вопросы не нужно отвечать один за другим, если кто-то может дать обзор шагов того, как и где асинхронные функции (например, setTimeout) переходят с момента первого обращения к стеку вызовов до момента их обратного вызова в стек вызовов.

  1. On step 3, who produces this new thread? Is it the browser?
    • This new thread is being blocked correct?
    • Что произойдет, если у вас есть цикл, который создает 1000 setTimeout. Создано 1000 «потоков»?
    • Есть ли ограничение на количество потоков, которые могут быть созданы одновременно?
    • Когда новый поток завершает выполнение, как он попадает в очередь?
  2. Кто поставляет очередь событий?
  3. Who supplies the Event Loop?
    • Does the event loop poll the Event Queue?
    • Знает ли поток javascript о цикле событий? Или цикл событий просто помещает вещи в стек?
    • Как цикл событий узнает, что стек чист?

person kurtcorbett    schedule 02.04.2015    source источник


Ответы (1)


Ваше понимание и ваш пример кажутся в основном правильными. Теперь к вашим вопросам:

На шаге 3, кто создает эту новую ветку? Это браузер?

да. По сути, это то, что обеспечивает реализацию этих «действительно асинхронных» функций. IIRC, setTimeout реализуется непосредственно в JS-движках, тогда как сетевой ввод-вывод определенно будет обязанностью браузера, но на самом деле не имеет значения, кто их создает. В конце концов, в вашей «среде браузера» это всегда какая-то часть браузера.

Эта новая ветка заблокирована правильно?

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

Что произойдет, если у вас есть цикл, который создает 1000 setTimeout. Создано 1000 «потоков»?

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

Есть ли ограничение на количество потоков, которые могут быть созданы одновременно?

Это будет контролироваться ОС.

Когда новый поток завершает выполнение, как он попадает в очередь? Кто поставляет очередь событий?

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

Кто поставляет петлю событий? Опрашивает ли цикл событий очередь событий?

Я бы сказал, что это деталь реализации, независимо от того, опрашивает ли цикл очередь или очередь управляет итерациями цикла.

Знает ли поток javascript о цикле событий? Или цикл событий просто помещает вещи в стек?

Я бы сказал, что javascript запускается в потоке цикла событий. Цикл событий просто многократно выталкивает события из очереди и выполняет их javascript.

Как цикл событий узнает, что стек чист?

Цикл событий вызывает выполнение javascript - поэтому стек очищается, когда javascript возвращается.

person Bergi    schedule 02.04.2015
comment
Мне потребовалось время, чтобы понять, что это хорошие ответы на мои вопросы. Я чувствую, что хорошая графика того, как браузер обрабатывает JS Engine, принесет большую пользу сообществу. Рассказ Филиппа Робертса о цикле событий также очень информативен по многим из этих аспектов. youtube.com/watch?v=8aGhZQkoFbQ - person kurtcorbett; 26.11.2015
comment
привет, у меня есть вопрос об асинхронной части: «Разработчик не может создавать свои собственные асинхронные функции» в исходном сообщении, если вы можете взглянуть, это будет очень полезно: stackoverflow.com/questions/53919515/ - person mzoz; 25.12.2018
comment
+ Берги большое спасибо и желаю счастливого Рождества! - person mzoz; 25.12.2018
comment
В MDN есть статья под названием Модель параллелизма и цикл событий. - person Dave F; 22.01.2019