Да. В JavaScript тоже бывает многопоточность 👐

«JavaScript однопоточный» - это про один поток на один контекст: главная вкладка или один воркер. Внутри такого контекста один event loop, одна очередь задач, никакой параллельности.

Но среда уже многопоточная: в браузере и в Node можно создать несколько воркеров. У каждого - свой поток и свой event loop. Они выполняются одновременно. Вопрос не «есть ли потоки», а «как они обмениваются данными и согласуют действия».

Раньше обмен был только через postMessage. Копируешь данные и всё, общей памяти нет. С SharedArrayBuffer появилась общая память. Несколько потоков пишут и читают одни и те же ячейки. Операции над ячейкой выполняются неделимо, никто не влезает между чтением и записью. В ECMAScript за это отвечает объект Atomics. Читать и писать: load, store, add, sub, compareExchange. Координация потоков: подожди значение в ячейке (wait, waitAsync) и разбуди ждущих (notify).

Почему это не «просто ещё один API» ❓

🔘 Без атомиков каждый воркер делает «прочитал число 👉 прибавил один 👉 записал». Второй может влезть между шагами первого, и сумма съедет. Atomics.add делает всё это одним шагом. Никто не влезает посередине. 🔘 Главный поток в браузере не умеет засыпать на wait, так устроена спецификация. Зато есть waitAsync. Вызвал его, получил промис. Воркер посчитал, записал в ячейку и нажал notify. Промис резолвится, читаешь результат. Вкладка не висит, ждать удобно.

Где это по делу используют ❓

🔘 Дашборд с выгрузкой отчётов. На экране «Обработано 142 из 1000». Воркеры крутят задачи и плюсуют в один счётчик через Atomics.add, главный читает и обновляет прогресс. Без атомиков число прыгает или теряется. 🔘 Браузерная игра. Физика и счёт очков в воркере пишут в SharedArrayBuffer, главный поток только рисует кадр и читает позиции. UI не подвисает, гонок нет. 🔘 Видеоплеер. Декодер крутится в воркере, кадр пишет в общую память и notify. Главный вызвал waitAsync, получил промис, отрисовал кадр. Не нужно опрашивать в цикле. 🔘 PWA с оффлайн-очередью. Воркер в фоне шлёт запросы из очереди. Главный ждёт waitAsync и обновляет UI: «отправлено 3 из 10». Всё без блокировки вкладки. 🔘 API на NestJS. Тяжёлый отчёт или генерация в Worker Thread. Задачи лежат в общей очереди (SharedArrayBuffer), воркеры забирают через compareExchange, по готовности notify. На сервере можно и wait, не только waitAsync.

Среда многопоточная - несколько агентов (главная вкладка, воркеры) работают параллельно. Каждый агент внутри себя однопоточный. Общая память и Atomics дают предсказуемую синхронизацию без гонок и без необходимости всё тащить через копирование сообщений. Для тяжёлых вычислений, очередей, счётчиков и «сигнала готовности» между потоками в JS это и есть нормальный многопоточный инструмент - по спецификации и на практике. #js

Да. В JavaScript тоже бывает многопоточность 👐 | Сетка — социальная сеть от hh.ru