Как многозадачность Javascript | Кодементор

Tl;dr Javascript работает очень быстро. Он просит браузер (на самом деле многопоточный) отключиться и сделать что-то и сообщить Javascript, когда это будет сделано. Затем движок Javscript доберется до него, когда он ничего не делает.

Возможно, вы слышали из разных источников, что Javascript является однопоточным. Это означает, что он может выполнять только одну команду за раз (как и большинство мужчин на Земле); тем не менее, ваш опыт работы в Интернете обычно включает в себя 2-3 вещи, происходящие одновременно. Это может быть любая комбинация

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

Итак, если все это происходит одновременно, как однопоточный движок Javascript делает все это беспроблемным? Краткий ответ, цикл событий.

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

Если вы зайдете в свою консоль javascript в своем браузере (вы можете найти в Google, как это сделать) и вставите следующий код в консольный ввод

while(true){}

Вы обнаружите, что теперь не можете ничего щелкнуть или прокрутить страницу. Это потому, что мы запустили бесконечный цикл, который не очистит куча (объясню это через несколько минут).


Ладно, к хорошему. Почти в каждой программе есть два вида памяти, которые ей доступны: куча и куча

Стек

изображение.png

Стек — это область памяти, в которой действуют особые правила добавления и удаления данных. Он ведет себя аналогично блинам, которые вы видите выше. Стеки — это то, что мы называем структурами данных «последним пришел — первым ушел». Это означает, что последний набор данных, который добавляется в стек, удаляется первым.

Если бы вы пекли блины, во время их приготовления вы бы перекладывали их на тарелку. Вы обнаружите, что последний, который вы приготовили, находится сверху. Блин сверху съедается первым. Стопка блинов работает по принципу LIFO (последним пришел, первым ушел).

Всякий раз, когда вы звоните function в Javscript эта функция context помещается в стек. Если эта функция вызывает другую функцию, она добавляется или «проталкивается» в стек. Как функции return они будут удалены или «вытолкнуты» из стека.

b2fcbdc1-0f26-44f3-8840-1e2fe3f182fe.gif

Когда стек пуст, движок Javascript выполняет ничего такого. Помните об этом.

Когда стек пуст, javascript выполняет ничего такого

Куча
изображение.png

Куча — это место, где хранится большая часть данных в программе. Здесь живут такие вещи, как объекты и массивы. Не зная точно, где что-то находится в куче, мы не сможем получить к нему доступ. Если бы у нас было немного иголка например, в куче, если бы мы хотели ее использовать, нам нужно было бы точно знать, где она находится (т.е. иметь прикрепленную к ней переменную)

В куче есть структура данных, присутствующая в каждой js-программе, которая называется message queue. Очередь сообщений действует подобно очередям, с которыми вы сталкиваетесь в повседневной жизни. Очередь ФИФО (первым прибыл, первым обслужен).

изображение.png

Если бы вы были первыми, кто встал в очередь за чем-то, вы также были бы первыми, кто был удален из очереди. Это верно для всех очередей, кроме очередей в аэропортах.

Хорошо, теперь у нас есть несколько частей:

  • В стек помещается контекст каждой вызываемой вами функции.
  • Куча — это место, где живут все большие данные
  • Очередь сообщений — это некоторая очередь, в которой хранятся сообщения (живет в куче)

Последний большой кусок браузер API (в Node это будет система API). Чтобы что-то делать с браузером, Javascript должен иметь некоторые функции, доступные из браузера для выполнения действий. Некоторые примеры:

  • принести
  • setTimeout
  • запросAnimationFrame
  • setInterval

Всякий раз, когда вы вызываете эти API, регистрируется обратный вызов, и в какой-то момент в будущем браузер вызовет этот обратный вызов.

setTimeout( function callback() {
  // run this code in 1 second
}, 1000 )

Когда этот обратный вызов называется его контекст помещается в очередь сообщений

Помните, я упомянул, что javascript делает ничего такого когда стек пуст? Всякий раз, когда javascript делает ничего такого какая-то волшебная машина возьмет следующую вещь из очередь сообщений и поместите его в стек. Эта волшебная машина называется цикл событий

изображение.png

На эту статью меня вдохновил замечательный доклад Уильяма Винсента о цикле событий Javascript. Изображение выше взято из его блога.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *