Skip to content

Пул воркеров ​

createWorkerPool() (vue-worker-kit/pool) — для множества мелких независимых задач (изменение размера сотен изображений и т. п.).

ts
import { createWorkerPool } from 'vue-worker-kit/pool'

const pool = createWorkerPool<typeof import('./resize.worker')>(
  () => new Worker(new URL('./resize.worker.ts', import.meta.url), { type: 'module' }),
)

// Заранее создать все воркеры до размера пула (опционально, избегает задержки холодного старта на первых задачах)
await pool.warmup()

// Обработка массива с передачей по элементу и глобальным сигналом отмены
const thumbnails = await pool.map(files, {
  concurrency: 4,
  transfer: (file) => [file.buffer], // zero-copy для каждого элемента
  signal: abortController.signal, // отменить все выполняющиеся задачи
})

const one = await pool.run(files[0])

Воркеры создаются лениво, до size, по мере поступления задач — не все сразу. size (опция) по умолчанию равен navigator.hardwareConcurrency — собственному числу логических ядер/потоков браузера на машине, где реально работает ваше приложение, а не числу, выбранному на этапе разработки. Передайте size явно, чтобы переопределить его (например, ограничить, или если navigator сообщает то, чему вы не доверяете — некоторые браузеры с усиленной приватностью ограничивают или округляют это значение). Откатывается к 4 там, где navigator не существует (SSR).

Методы ​

pool.run(input, options?) ​

(input: In, options?: RunOptions) => Promise<Out>

Ставит задачу в очередь первому свободному воркеру.

  • transfer?: Transferable[] — список zero-copy передачи для этой задачи
  • signal?: AbortSignal — отменяет эту задачу
  • onProgress?: (value: number) => void — получает вызовы ctx.reportProgress() этой задачи
  • onChunk?: (chunk: unknown) => void — получает вызовы ctx.reportChunk() этой задачи

pool.map(items, options?) ​

(items: In[], options?: MapOptions) => Promise<Out[]>

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

  • concurrency?: number — максимум параллельных задач (по умолчанию: pool.size)
  • transfer?: (item: T) => Transferable[] — функция передачи zero-copy для каждого элемента
  • signal?: AbortSignal — глобальный сигнал отмены для всех элементов
  • onProgress?: (value: number) => void — один callback, общий для всех элементов пакета
  • onChunk?: (chunk: unknown) => void — один callback, общий для всех элементов пакета

Отчёты о прогрессе и чанках ​

В отличие от useWorker()/useSharedWorker(), у пула нет постоянного ref progress/chunks — одновременно может выполняться множество задач в разных слотах, поэтому нет единого значения, которое можно было бы предоставить. Вместо этого передавайте onProgress/onChunk напрямую в pool.run() или pool.map():

ts
await pool.run(input, {
  onProgress: (value) => console.log('прогресс', value),
  onChunk: (chunk) => console.log('чанк', chunk),
})

await pool.map(items, {
  onProgress: (value) => console.log('прогресс', value), // срабатывает для того элемента, который сейчас отчитывается
  onChunk: (chunk) => console.log('чанк', chunk),
})

Для map() одна и та же пара onProgress/onChunk общая для всего пакета — callback'а на каждый элемент отдельно нет, поэтому если нужно знать, какому элементу принадлежит конкретное значение прогресса или чанк, эту информацию нужно закладывать в само значение/чанк (например, обработчику воркера включать в отчёт входные данные или id).

Обработчик, написанный для useWorker()/useSharedWorker() и вызывающий ctx.reportProgress()/ctx.reportChunk(), без изменений работает и под пулом — он не знает, какой composable им управляет, — но эти вызовы можно наблюдать, только если передать onProgress/onChunk в RunOptions/MapOptions; иначе они отбрасываются (см. Потоковая передача результатов — там же описано предупреждение в режиме разработки, которое в этом случае выводится).

pool.stats ​

ComputedRef<{ busy: number; idle: number; queued: number }>

Реактивно, используется панелью devtools.

pool.terminate() ​

() => void

Завершает весь пул.

pool.warmup() ​

() => Promise<void>

Заранее создаёт все воркеры до size, не выполняя задачи.

Вариант для Vue-composable ​

useWorkerPool()

Тот же API, что и у createWorkerPool(), но с автоматическим завершением через onScopeDispose для использования прямо в setup() — используйте этот вариант, когда время жизни пула должно совпадать с временем жизни компонента.