JavaScript и« Java - совершенно разные языки, как по концепции, так и по дизайну».
JavaScript - это высокоуровневый, часто компилируемый точно в срок и мультипарадигмальный язык программирования.
точно в срок - код компилируется тогда, когда это необходимо, а не до выполнения.
мультипарадигма - javaScript поддерживает как объектно-ориентированное программирование с прототипным наследованием, так и функциональное программирование.
JavaScript был создан Бренданом Эйхом из Netscape в 1995 году. Первоначально он задумывался как более простой язык сценариев для веб-сайтов, дополняющий использование Java для более сложных веб-приложений, но его тесная интеграция с веб-страницами и встроенными функциями. Поддержка в браузерах привела к тому, что он стал гораздо более распространенным, чем Java, в веб-разработке.
Но в отличие от других языков программирования, javascript однопоточный. Это означает, что выполнение кода в js выполняется последовательно, что означает, что мы можем столкнуться с тем, что один фрагмент кода блокирует другой фрагмент кода.
Когда вы посещаете сайт в своем браузере, начинает работать единственный поток выполнения javascript. Этот поток отвечает за обработку всего, например прокрутки, прослушивания событий DOM, таких как щелчки мыши, печати веб-страницы. Когда это единственное выполнение заблокировано, веб-страница перестает отвечать.
Так как же с этим справляется javascript?
когда происходит асинхронное событие (например, щелчок мышью, срабатывание таймера или завершение XMLHttpRequest), оно ставится в очередь для выполнения позже…. После того, как начальный блок JavaScript завершает выполнение, браузер сразу же задает вопрос: что ожидает выполнения? Затем браузер выбирает один и немедленно выполняет его. Остальные будут ждать до следующего возможного раза, чтобы выполнить.
Для понимания это позволяет сначала понять время выполнения javascript.
Стек вызовов - область памяти, работающая в режиме FIFO. Когда компьютерная программа запускает новый поток, создается новый стек. Движок Js начинает подталкивать функции для выполнения в стеке вызовов, начиная с родительской функции.
Когда функция возвращает значение или вызывает веб-API, она извлекается из стека и переходит к следующей функции в стеке. Этот процесс синтаксического анализа функции и извлечения ее из стека - вот что они имеют в виду, когда говорят, что Javascript выполняется синхронно. Он выполняет одно действие в одном потоке.
Например
function main(){ //3 average() //2 } function average(){ add() //1 } main()
функция выполняется в порядке 1- ›2-› 3
Куча -
Здесь движок V8 хранит объекты или динамические данные. Это самый большой блок области памяти, и именно здесь происходит Сборка мусора (GC).
Стеки против кучи
- Каждый вызов функции добавляется в стек.
- Все локальные переменные, включая аргументы и возвращаемое значение, сохраняются в блоке кадра функции в стеке.
- Все примитивные типы, такие как
int
иstring
, хранятся непосредственно в стеке. Это относится и к глобальной области видимости, и да, String - это примитивный тип в JavaScript. - Все типы объектов создаются в куче, и на них ссылаются из стека с помощью указателей стека. Функции - это просто объекты в JavaScript. Это относится и к глобальной области видимости.
- Функции, вызываемые из текущей функции, помещаются в верхнюю часть стека.
- Когда функция возвращает, ее кадр удаляется из стека.
- После завершения основного процесса объекты в куче больше не имеют указателей из стека и становятся бесхозными.
- Если вы не сделаете копию явно, все ссылки на объекты внутри других объектов выполняются с использованием ссылочных указателей.
Поскольку JavaScript является однопоточным, у него только один стек и одна куча. Следовательно, если какая-либо другая программа хочет выполнить что-то вроде HTTP-запроса, она должна дождаться полного выполнения предыдущей программы. Это действительно плохо для любого языка программирования. Упс
Здесь вступают в действие цикл событий и очереди обратного вызова.
Итак, что происходит на самом деле
В браузере постоянно происходит множество вещей, таких как HTTP-вызовы, события щелчка мыши, задержка выполнения с использованием функции setTimeOut () и множество прокрутки ... представьте, что все эти задачи выполняются одним потоком, не ухудшит ли это взаимодействие с пользователем
Итак, что делает браузер, так это то, что он использует язык низкого уровня, такой как C++
, для выполнения этих операций и предоставляет чистый асинхронный JavaScript API для работы. Эти API-интерфейсы известны как веб-API.
Давайте разберемся с асинхронным поведением с помощью кода.
function main(){ average() } function average(){ //2 add() } function add(){ //3 setTimeout(callback,3000) //4 } main() //1
В стеке вызовов, как передаются функции
1 →2 →3 →4
4 содержит вызов веб-API, поэтому он передается веб-API с функцией обратного вызова и извлекается из стека. Затем выполняются и извлекаются 3 - ›2-› 1.
Между тем, веб-API выполняет свою работу в фоновом режиме, и после завершения работы веб-API связывает результат этого задания с функцией обратного вызова и публикует сообщение в очередь обратного вызова с этим обратным вызовом.
Единственная задача цикла обработки событий - смотреть на очередь обратного вызова, и как только в очереди обратного вызова есть что-то незавершенное, отправить этот обратный вызов в стек.
Цикл обработки событий отправляет в стек по одной функции обратного вызова, когда стек пуст. Позже стек выполнит функцию обратного вызова.
Заключение
Вот как javascript обрабатывает выполнение задачи в браузере. Node js - это среда выполнения javascript, в которой используется механизм Google V8. Но Nodejs полагается не только на свой цикл обработки событий. Он использует библиотеку libuv, написанную на языке c, для работы вместе с циклом обработки событий V8 для расширения того, что можно делать в фоновом режиме.
NodeJS имеет цикл событий и может выгружать задачи в свой пул внутренних потоков или ядро, чтобы выполнять код, пока он ожидает ввода-вывода, что позволяет NodeJS обрабатывать множество запросов одновременно, даже если он является однопоточным.