Call Stack & Event loop - зачем ждать пустой стек?

1

Я знаю, что сообщения попадают в стек вызовов из очереди, когда стек вызовов пуст. Было бы лучше, если бы цикл событий мог отправлять сообщения из очереди непосредственно в стек вызовов, не дожидаясь ожидания? Каковы причины этого поведения? Если цикл события будет толкать сообщение в точное время, мы всегда можем полагаться на такие функции, как 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, но я не мог найти ничего подобного: "Почему цикл событий работает именно так". Любая помощь будет принята с благодарностью.

  • 0
    Возможная копия поведения setTimeout с кодом блокировки
  • 0
    Я знаю, почему это так работает. Я хочу знать, почему архитектура была реализована таким образом, хотя
Показать ещё 2 комментария
Теги:
v8
event-loop

1 ответ

4
Лучший ответ

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

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

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

  • 0
    Спасибо за ваше объяснение. Это имеет смысл для меня прямо сейчас. Вы знаете какие-то дополнительные ресурсы по этому вопросу? Я хотел бы узнать больше о технических деталях, связанных с циклом событий, и как это происходит, когда сообщения приходят из очереди в стек.
  • 0
    Вы можете думать о «цикле событий» как о списке замыканий, ожидающих вызова. Когда управление возвращается в цикл обработки событий (т. Е. Возвращалось ранее вызванное замыкание), вызывается следующее ожидающее закрытие. Это запускает новый стек вызовов (как объяснено выше, «стек вызовов» не является структурой данных, он просто описывает тот факт, что функции вызывают друг друга, образуя стековый поток управления).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню