> Как использовать несколько потоков в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: intelsy
Стек: JavaScript
> Пример ответа
Короткий ответ
JavaScript - однопоточный язык с event loop, но многопоточность доступна через Web Workers (браузеры) и Worker Threads (Node.js). Они создают изолированные потоки с собственным контекстом, общающиеся через сообщения (postMessage). Для CPU-интенсивных задач используют также SharedArrayBuffer для разделяемой памяти и Atomics для синхронизации. Основной поток не блокируется, но workers не имеют доступа к DOM или глобальным объектам.
Подробное объяснение
В JavaScript исторически нет настоящей многопоточности из-за однопоточной модели event loop. Однако для параллельного выполнения существуют:
-
Web Workers (браузеры): создаются через
new Worker('script.js'). Каждый worker работает в отдельном потоке, не имеет доступа к DOM, window, document. Общение - черезpostMessageи событиеmessage. Workers могут быть вложенными и создавать subworkers. -
Worker Threads (Node.js): модуль
worker_threads. Аналогичны Web Workers, но имеют доступ к Node.js API (кроме некоторых). Используются для CPU-нагрузки, например, обработки изображений или шифрования. -
SharedArrayBuffer: позволяет нескольким потокам читать/писать общую память. Требует заголовков безопасности (Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy). Используется с Atomics для атомарных операций и синхронизации.
-
Service Workers: не для многопоточности в классическом смысле, но работают в фоновом потоке для перехвата запросов и кэширования.
-
OffscreenCanvas: позволяет рендерить графику в worker.
Ограничения: workers не могут напрямую изменять DOM, требуют сериализации данных (структурное клонирование или transferable objects), имеют накладные расходы на создание.
На практике
Используйте workers для:
- Тяжелых вычислений (криптография, парсинг данных, обработка медиа)
- Фоновой загрузки и обработки файлов
- Реалтайм-аналитики (например, обработка аудиопотока)
- Параллельных запросов к API (хотя это можно сделать через Promise.all)
Не используйте workers для:
- Простых операций (накладные расходы выше выгоды)
- Частого обмена большими данными (лучше transferable objects)
- Работы с DOM (используйте основной поток)
На практике часто создают пул workers для балансировки нагрузки. В Node.js worker_threads удобны для изоляции тяжелых модулей, чтобы не блокировать основной поток сервера.
Пример кода
JAVASCRIPT// main.js (браузер)const worker = new Worker('worker.js');worker.postMessage({ type: 'compute', data: [1, 2, 3, 4, 5] });worker.onmessage = (event) => {console.log('Результат:', event.data);};// worker.jsself.onmessage = (event) => {const { data } = event.data;const result = data.reduce((acc, val) => acc + val, 0);self.postMessage(result);};
JAVASCRIPT// Node.js с worker_threadsconst { Worker } = require('worker_threads');const worker = new Worker('./worker.js', { workerData: { numbers: [1, 2, 3] } });worker.on('message', (result) => console.log('Результат:', result));worker.on('error', (err) => console.error(err));
Как отвечать на собеседовании
Начните с признания однопоточности JS, затем перечислите механизмы многопоточности. Упомяните различия между браузером и Node.js. Приведите пример, когда workers оправданы. Покажите понимание ограничений (DOM, сериализация). Если спросят про SharedArrayBuffer, объясните его назначение и требования безопасности. Избегайте путаницы с асинхронностью (async/await не делают код многопоточным).
Что проверяет интервьюер
- Понимание event loop и однопоточной модели
- Знание конкретных API (Web Workers, Worker Threads)
- Умение выбирать правильный инструмент под задачу
- Понимание trade-off (накладные расходы, изоляция, безопасность)
- Знание продвинутых тем (SharedArrayBuffer, Atomics, transferable objects)
Типичные ошибки
- Путать асинхронность с многопоточностью (setTimeout не создает поток)
- Пытаться использовать workers для DOM-операций
- Забывать про сериализацию данных (передавать функции или циклические ссылки)
- Создавать worker на каждую мелкую задачу (лучше пул)
- Игнорировать заголовки безопасности для SharedArrayBuffer
- Думать, что workers в Node.js имеют полный доступ ко всем модулям (некоторые ограничены)
> Похожие задачи по frontend
Как реализовать возврат true или false в полифилле some для прерывания перебора при первом true?
Как реализовать полифилл для Array.prototype.some с учетом callback и thisArg?
Как записывать ошибки в массив по индексу, соответствующему индексу промиса в JavaScript?
Что такое замыкания в JavaScript и для чего они нужны
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью