freeCodeCamp/guide/russian/javascript/concurrency-model-and-event.../index.md

9.6 KiB
Raw Blame History

title localeTitle
Concurrency Model and Event Loop Модель параллелизма и цикл событий

Модель параллелизма и цикл событий

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

Стек вызовов представляет собой простую структуру данных, которая записывает, где в коде мы в настоящее время. Поэтому, если мы входим в функцию, которая является вызовом функции, она помещается в стек вызовов, и когда мы возвращаемся из функции, она выплывает из стека.

Давайте рассмотрим пример кода, чтобы понять стек вызовов,

function multiply(x,y) { 
   return x * y; 
 } 
 
 function squared(n) { 
     return multiply(n,n) 
  } 
 
 function printSquare(n) { 
   return squared(n) 
 } 
 
 let numberSquared = printSquare(5); 
 console.log(numberSquared); 

Во-первых, когда код выполняет runtime, он будет считывать каждое из определений функций, но когда он достигнет строки, в которой вызывается первая функция printSquare (5), она будет вызывать эту функцию в стек вызовов. Затем эта функция будет выполнена, и перед возвратом она встретит другую квадрат функции (n), чтобы приостановить ее текущую операцию и нажать эту функцию поверх существующей функции. Он выполняет функцию в этом случае в квадратной функции и, наконец, встречает другую функцию multiply (n, n), поэтому он приостанавливает выполнение своих текущих исполнений и толкает эту функцию в стек вызовов. Функция умножается, и возвращается с умноженным значением. Наконец, функция квадратов возвращается и выталкивается из стека, а затем то же самое происходит с printSquare. Конечное квадратное значение присваивается переменной numberSquared. Мы снова сталкиваемся с вызовом функции, в этом случае это оператор console.log (), поэтому среда выполнения выталкивает это в стек, который выполняет его, тем самым печатая квадрат числа на консоли. Следует отметить, что первая функция, которая попадает в стек до того, как выполняется какой-либо из вышеперечисленных программ, является основной функцией, которая в среде выполнения обозначается как «анонимная функция».

Поэтому, чтобы суммировать всякий раз, когда вызывается функция, она помещается в стек вызовов, где она выполняется. Наконец, когда функция выполняется с ее выполнением и возвращается либо неявно, либо явно, она будет удалена из стека. Стек вызовов просто записывает в какой момент времени исполняемый функционал. Он отслеживает, какая функция в данный момент выполняется.

Теперь мы знаем, что Javascript может выполнять одну вещь одновременно, но это не так с браузером. У браузера есть собственный набор API, таких как setTimeout, XMLHttpRequests, которые не указаны в среде выполнения Javascript. На самом деле, если вы посмотрите исходный код V8, популярную среду исполнения Javascript, которая поддерживает браузеры, такие как Google Chrome, вы не найдете никаких определений. Это связано с тем, что эти специальные веб-API существуют в среде браузера, а не в среде javascript, и вы можете сказать, что эти apis вводят параллелизм в микс. Давайте посмотрим на диаграмму, чтобы понять всю картину.

Модель параллелизма и события

Введены еще несколько терминов

Куча - это в основном место, где выделяются объекты.

Callback Queue - это структура данных, в которой хранятся все обратные вызовы. Так как это очередь, поэтому элементы обрабатываются на основе FIFO, который является первым в First Out.

Event Loop - это то, где все эти вещи объединяются. То, что цикл событий просто делает, это проверять стеки вызовов, и если он пуст, что означает, что в стеке нет функций, он принимает самый старый обратный вызов из очередь обратного вызова и толкает ее в стек вызовов, который в конечном итоге выполняет обратный вызов.

Давайте разобраться с примером кода -

console.log('hi'); 
 
 setTimeout(function() { 
     console.log('freecodeCamp') 
 },5000); 
 
 console.log('JS') 

Когда выполняется первая строка, это console.log (), который является вызовом функции, что означает, что эта функция помещается в стек вызовов, где она выполняет печать «привет» на консоль и, наконец, возвращается и выталкивается из стека. Затем, когда среда выполнения запускает setTimeout (), она знает, что это веб-API, и, следовательно, он отдает браузеру его выполнение. Браузер запускает таймер, а затем среда выполнения JS выталкивает setTimeout () из стека. Он встречает другой вызов console.log (), и поэтому он толкает его в стек вызовов, сообщение «JS» записывается в консоль, а затем оно наконец возвращается, и поэтому последний console.log () удаляется из стека. Теперь стек вызовов пуст. Между тем, пока все это продолжалось, таймер заканчивается, когда прошло 5 секунд, браузер идет вперед и толкает функцию обратного вызова в очередь обратного вызова. Далее цикл событий проверяет, свободен ли стек вызовов или нет. Поскольку он свободен, он выполняет функцию обратного вызова и снова возвращает его в стек вызовов, который выполняет внутри него код. Снова внутри кода есть вызов console.log (), поэтому эта функция переходит в верхнюю часть стека, которая записывает «freecodecamp» в консоль, и, наконец, возвращает, что означает, что она удаляется из стека, и, наконец, обратный вызов всплывает и мы закончили.

Чтобы визуализировать это, лучше попробуйте этот инструмент с помощью Phillip Roberts-Loupe Event Loop Visualizer

Дополнительная информация:

Филипп Робертс: Какая черта - цикл событий? | ОАО «Союз 2014»

Модель параллелизма и Event Loop MDN