Vite 中使用 worker-pool

1,821 阅读2分钟

使用 worker-pool

  1. 安装 workerpool

    在你的项目中安装 workerpool

    npm install --save workerpool
    
  2. 配合 Vite 使用

    MyWoker.ts

    import WorkerPool from "workerpool";
    
    const compute = async (uploadFile: UploadFile) => {
        const file = uploadFile.file;
        const spark = new SparkMD5.ArrayBuffer();
        // 省略
        // 返回最终 md5
        return spark.end();
    }
    
    // 创建一个 worker 并注册函数
    WorkerPool.worker({
        compute: compute,
    });
    

    主线程中:

    const md5 = (uploadFiles: UploadFile[]) => {
      // 创建 pool 
      const pool = WorkerPool.pool(new URL('/src/utils/worker/md5/ComputeMD5.ts', import.meta.url).href, {
        workerType: 'web',
        workerOpts: { type: 'module' }
      });
      const promises = uploadFiles.map(async (uploadFile) => {
        uploadFile.folder.md5 = await pool.exec('compute', [uploadFile], {
          // 监听进度
          on: (payload) => {
            console.log(`${uploadFile.name} 进度: ${payload.progress}`);
          }
        });
      });
      // Promise.all(promises);
    }
    
  3. 更详细的用法:https://www.npmjs.com/package/workerpool

workerpool 的创建和销毁

使用 workerpool 库,在工作线程池中创建和销毁 workers 是一个自动化处理的过程,工作线程池的目的就是为了管理 workers 的生命周期,避免了手动创建和销毁 worker 的麻烦。

创建 Worker

当工作线程池 (workerpool.pool) 被实例化时:

  1. workerpool 会基于配置(如最大工作线程数 maxWorkers)创建一定数量的 workers。
  2. 每个 worker 将被实例化为一个单独的工作线程,并加载指定的脚本或模块。
  3. 一旦创建,workers 会在池中待命,等待被分配任务。

分配任务

当你调用 pool.exec() 执行一个函数时:

  1. workerpool会在内部选择一个空闲的 worker。
  2. 然后,所选 worker 将被分配该任务并开始执行。
  3. 如果所有 workers 都在忙,新的任务会被排队等候直到有 worker 变成空闲状态。

销毁 Worker

关于workers的销毁,workerpool 处理得也很智能:

  1. 默认情况下,workers 在它们完成所有已被分配的任务后,会继续在池中待命。对于后续的任务,可以重用这些 workers,提升效率。
  2. 可以配置 workerpool 在一个 worker 完成任务后自动销毁。这可以使用 WorkerPool 构造参数中的workerType 属性来设置。
  3. 你也可以手动销毁工作线程池。这通过调用 pool.terminate() 完成。当你调用此函数时,它会优雅地结束所有活跃的 workers 并且销毁整个池。所有未处理的任务都会被取消。

这个自动管理的过程意味着,在开发者视角,你只需关心你想要执行的任务,而不是 workers 的生命周期。这种情况下, workerpool 帮你隐藏了 worker 的创建和销毁的复杂性,只暴露简洁和高效的 API 供你调用。