Comments 12
JavaScript - это синхронный однопоточный язык
Не бывает "однопоточных" и "многопоточных" языков. Бывают соответствующие среды исполнения. В языке может быть синтаксическая обертка над вызовом функции запуска потока (или иных действий с потоками), но суть от этого не меняется.
Для js основные среды исполнения (браузер и нода) уже давно умеют создавать самые обычные потоки-воркеры.
Вы про web worker (в браузере)?
ага
А разве web worker это не костыль для узкого спектра задач? Если в golang я могу любые задачи разбить на горутины, то web worker выполняет какую-то работу для основного процесса. У них нет общего контекста исполнения(только через api).
Разве я могу с помощью web worker распараллелить обработку DOM событий, рендеринг элементов или любые другие вычисления в контексте одного конкретного документа?
Поправьте меня, если я не прав.
Да, воркеры - сугубо числодробильня, они занимаются cpu-bound задачами, дабы не тормозить основной поток. С домом и отрисовкой они не помогают. Да и не совсем понятно, как могли бы помочь. Модифицировать дом-дерево? В оном не бывает такого большого количества изменений на единицу времени, кроме совсем уж "узкого спектра задач". Рефлоу/репаинт? Это делается в основном потоке на, условно, каждом витке событийного цикла, а не когда вздумается. Там больше ресурсов уйдет на синхронизацию этого дела между потоками. Совместный доступ к дому не нужен, имхо.
А вот, допустим, забабахать какой-нибудь сложный фильтр для здоровенной картинки с канвы - самое то. Берутся попиксельные данные, отправляются в воркер (не копируются, а просто передаются), после обработки присылаются обратно. В роли синхронизатора - механизм сообщений между потоками.
Если хочется компактно и сиюминутно запустить воркер, не создавая к нему отдельный js-файл, а прямо вот передать функцию, то можно код этой функции положить в блоб, взять от блоба URL.createObjectURL с ним создать воркер. При отсутствии в функции замыканий и ссылок на кастомные объекты, всё отработает как надо.
Берутся попиксельные данные, отправляются в воркер
т.е. чисто теоретически, делегируем другому процессу. Если убрать тайминговые накладки, то то же самое я мог бы отправить на какой-то сервер, делегировав ему.
cpu-bound задачами
Можете из опыта набросать список таких задач, для расширения моего кругозора.
Модифицировать дом-дерево?
На глазок, setTimeout/interval, колбеки событий (например скрол, движения мыши). Да та же сортировка, фильтрация больших объемов данных, без лишних накладок в виде пересылки их куда-либо.
В вебе примерно как в андроиде — есть UI-тред, к нему много чего привязано и, конечно, можно сделать отдельные потоки для выполнения чего-либо, но как правило не очень нужно.
Точно не знаю, но сомневаюсь, что в golang по-другому — если делать UI на golang, точно так же у вас будет UI-тред, от которого вы вряд ли уйдете далеко. Если в го реально можно повесить скролл интерфейса на другой поток, то отпишитесь плиз, я присмотрюсь, это прям интересно
Я скорее согласен с вами, чем с автором. С одним уточнением — если в языке нет никаких (языковых) механизмов синхронизации потоков, при многопоточной среде исполнения писать на нем будет не так удобно. Можно конечно все через библиотеки, но разница все-таки будет, и временами довольно заметная. Ну т.е. есть языки, которые с рождения учитывают, что среда будет многопоточная, и есть такие, к которым ее прикрутили позже.
Ну, например, когда-то я кодил на WinApi, на плюсах. Там, разумеется, были и потоки, и объекты синхронизации, причем всё в виде обычных функций (а не специального синтаксиса) из какого-то заголовочного файла, уже не помню какого. И ничего, вроде норм. было.
В браузерном js есть 3 кейса: 1) обычные данные, которые не шарятся между потоками (копируются при передаче) и не требуют синхронизации, 2) бинарные массивы, которые передаются в поток, становясь недоступными для отправителя, 3) некие SharedArrayBuffer, которые совсем общие и доступ к ним надо синхронизировать (для чего имеется тоже какой-то механизм, но я пока не вкуривал).
Ну, это уже вопрос вкуса. Я не говорю, что так нельзя. Я говорю, что с подержкой на уровне языка сильно удобнее. Да и структуры данных, например — взять тот же js, и скажем java. Во втором случае у вас есть структуры, которые готовы к многопоточной среде. В первом же — если она вдруг станет многопоточной, возможно что угодно. То есть, сломаться может любой кусок кода, не обернутый в вызовы нужных функций синхронизации. Когда вы заранее пишете под многопоточность — вы об этом думаете. Когда вы вводите ее потом — уже не всегда.
И зачем только люди Douglas'a Crockford'a читают?
*Наверное, затем, что если всех индусов читать, никакой жизни не хватит.*
Как работает JavaScript [Объясняю визуально]