Call Stack & Event loop - зачем ждать пустой стек? - PullRequest
0 голосов
/ 20 октября 2018

Я знаю, что сообщения поступают в стек вызовов из очереди, когда стек вызовов пуст.Разве не было бы лучше, если бы цикл обработки событий мог отправить сообщения из очереди напрямую в стек вызовов без ожидания?Какие причины стоят за этим поведением?Если цикл обработки событий отправит сообщение в точное время, мы всегда можем положиться на такую ​​функцию, как setTimeout и т. Д.

setTimeout(() => console.log("I want to be logged for 10ms, but I will never be :("), 10);

// some blocking operations
for(let i = 0; i < 500000000; i++){
  Math.random() * 2 + 2 - 3;  
}

console.log("I'll be logged first lol");

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

1 Ответ

0 голосов
/ 21 октября 2018

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

Вы могли бы создать концептуальную среду программирования, которая была бы концептуально схожей, но не помещала бы что-либо в стек вызовов,он будет прерывать и приостанавливать все, что в данный момент выполняется, и вместо этого выполнять запланированную setTimeout функцию (или обработчик событий и т. д.) и впоследствии возобновлять предыдущее выполнение.Одна проблема, которую вам нужно решить: что, если это повторяется, то есть что, если запланированная функция прерывается другой запланированной функцией, которая прерывается другой запланированной функцией, и так далее?Что если запланированная функция завершается вечно: когда исполняемый ранее код снова начинает прогрессировать?Кроме того, хотя это может быть сделано в однопоточном мире, получение случайных прерываний - это параллелизм (что с точки зрения согласованности эквивалентно параллелизму / многопоточности), поэтому вам понадобятся примитивы синхронизации, такие как блокировки (по сути, имеютспособ для функций сказать «не прерывайте этот раздел» - что, в свою очередь, означает, что вы не можете гарантировать точность планирования запросов).Не стоит недооценивать сложность, которую все это может навязать программистам: при написании кода им следует помнить, что в любой момент может произойти прерывание всего, а с другой стороны, любые данные, которые одна функция может захотеть обработать.может быть еще не готова, потому что другая функция, которая ее произвела, еще не завершила работу.

Короче говоря, система циклов обработки событий JavaScript - это то, чем она является, потому что язык избегает параллелизма, и случайное прерывание функций для выполнения другихпараллелизм, даже в однопоточной системе.

...