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

66 lines
9.6 KiB
Markdown
Raw Normal View History

2018-10-12 20:00:59 +00:00
---
title: Concurrency Model and Event Loop
localeTitle: Модель параллелизма и цикл событий
---
## Модель параллелизма и цикл событий
Время выполнения Javascript однопоточное, что означает, что он может выполнять один фрагмент кода за раз. Чтобы понять модель параллелизма и цикл событий в 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 вводят параллелизм в микс. Давайте посмотрим на диаграмму, чтобы понять всю картину.
![Модель параллелизма и события](https://i.imgur.com/rnQEY7o.png)
Введены еще несколько терминов
**Куча** - это в основном место, где выделяются объекты.
**Callback Queue** - это структура данных, в которой хранятся все обратные вызовы. Так как это очередь, поэтому элементы обрабатываются на основе FIFO, который является первым в First Out.
**Event Loop** - это то, где все эти вещи объединяются. То, что цикл событий просто делает, это проверять стеки вызовов, и если он пуст, что означает, что в стеке нет функций, он принимает самый старый обратный вызов из очередь обратного вызова и толкает ее в стек вызовов, который в конечном итоге выполняет обратный вызов.
Давайте разобраться с примером кода -
```javascript
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](http://latentflip.com/loupe/?code=!!!PGJ1dHRvbj5DbGljayBtZSE8L2J1dHRvbj4%3D)
#### Дополнительная информация:
[Филипп Робертс: Какая черта - цикл событий? | ОАО «Союз 2014»](https://www.youtube.com/watch?v=8aGhZQkoFbQ)
[Модель параллелизма и Event Loop MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)