24 месяца назад

Около 24 месяцев назад я стал стажером-разработчиком JavaScript.

Я подумал про себя, как на самом деле работает JavaScript? Я не был полностью уверен, я слышал термин V8, исполняющая среда Chrome на самом деле не знала, что это значит и что это делает. Я слышала такие вещи, как однопоточность.

мне интересно узнать

Я начал путешествие, читая, исследуя и экспериментируя в браузере.

JavaScript Кто ты?

То, что я получил из интернета, это

Я однопоточный, неблокирующий, асинхронный параллельный язык.

У меня есть стек вызовов, цикл событий, очередь обратного вызова, некоторые другие API и прочее.

Вопрос: Эй, V8, у вас есть стек вызовов, цикл событий, очередь обратного вызова, некоторые другие API и прочее?

A: У меня есть стек вызовов и куча. (Подождите, что!!, что это за другие вещи??)

3 месяца спустя… [Кажется, я понял]

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

Итак, если вы посмотрите на саму среду выполнения JavaScript, такую ​​​​как V8, которая является средой выполнения внутри chrome

Если вам нравится клонировать кодовую базу V8 и выполнять grep для таких вещей, как setTimeout, DOM или HTTP-запросы, их там нет, их нет в V8, что было для меня неожиданностью.

Итак, за эти 24 месяца открытий я пришел к пониманию, что на самом деле это более широкая картина, это то, что я надеюсь привлечь вас к себе.

У нас есть среда выполнения V8, но затем у нас есть такие вещи, как веб-API, которые являются дополнительными вещами, предоставляемыми браузером, и у нас есть этот цикл событий и очередь обратного вызова.

Стек вызовов

один поток == один стек вызовов == одна вещь за раз

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

Пример выполнения кода со стеком вызовов

Выполнение программы начинается с main() и при подходе сверху вниз она посещает все три функции, в третьей функции она получила printSquare()вызов функции printSquare(4) а затем в printSquare() { var squared = square(n)} другой вызов функции, который является square(n), он помещается в стек, и в этом function square(n) { return multiply(n, n)} еще один вызов функции, теперь multiply(n, n) помещается в стек.

В этом умножить (a, b) { return a* b; } . Как только функция возвращается, она удаляется из стека.

Таким же линейным образом square(n) и printSquare(n) выскакивают из стека и завершают функцию.

Если вы слышали такой термин, как взорвать стек, это пример того, что

Давайте посмотрим на этот пример

Блокировка

Что происходит, когда все идет медленно?

Что на самом деле означает блокировка, код, который замедляет выполнение и долго остается в стеке вызовов, приводит к блокировке простого примера console.log('hello..'). не медленный, но в то время как (i≤100000000) определенно медленный.

Какое решение для этого? Почему это проблема?

Потому что браузеры (мы запускаем код в браузерах)

Решение: асинхронные обратные вызовы

Асинхронные обратные вызовы и стек вызовов

Итак, асинхронные обратные вызовы со стеком, как это работает. давайте посмотрим на этот код.

console.log('привет');

setTimeout (функция () { console.log («там»); }, 5000);

console.log('Добро пожаловать в мой блог');

Отладка кода со стеком

console.log('привет'); поместить в стек и вывести в консоль браузера.

setTimeout(cb, 5000); мы знаем, что он не запустится сразу, мы знаем, что он запустится через 5 секунд. значит, мы не можем запихнуть его в стек, и где он останется?? мы переходим к следующему

console.log("Добро пожаловать в мой блог"); поместить в стек и распечатать.

Через 5 секунд console.log('здесь'); поместить в стек и распечатать.

Как это происходит??

Ответ: Цикл параллелизма и событий (одна вещь за раз, но не совсем)

Это в основном, где цикл событий входит в параллелизм.

Среда выполнения JavaScript может выполнять одну операцию за раз. Это правда. Причина, по которой мы можем делать что-то одновременно, заключается в том, что браузер — это больше, чем просто среда выполнения.

Среда выполнения JavaScript может делать одну вещь за раз, но браузер предоставляет нам другие вещи, такие как веб-API, которые фактически представляют собой потоки, к которым вы можете просто обращаться, и эти части браузера знают об этом «параллелизме». .

Давайте посмотрим, как все меняется, когда на сцену выходят параллелизм и очередь.

console.log('привет');

setTimeout (функция () {

console.log('Как дела!');

}, 5000);

console.log('Добро пожаловать');

Сначала он переходит в console.log('hi'); сразу же он помещается в стек и печатает

Затем идет setTimeout(cb, 5000), он немедленно завершится и поместит его в очередь, помните о цикле событий, он должен подождать, пока стек не будет очищен, прежде чем он сможет поместить обратный вызов в стек, так что ваш стек будет продолжать работать. console.log('Добро пожаловать в мой блог'); ясно, теперь цикл обработки событий может запуститься и вызвать обратный вызов, поместить его в стек и вывести .

Вот как JavaScript становится неблокирующим и асинхронным параллельным языком. Вот и все. Не стесняйтесь комментировать, мне всегда любопытно и интересно узнавать новые мысли и делиться ими. Спасибо.