Web Worker简单封装 - 2024-09-12

/**
 * Web Worke 封装
 * @param task 耗时任务function (task 必须为纯函数,且不可使用外部变量或调用外部函数)
 * @param deps task任务执行依赖
 * @returns Promise<T> 
 */
export function executeTaskByWorker<T = any>(task: () => T, deps?: Record<string, any>): Promise<T> {
  const dependencies = Object.keys(deps || {})
    .map(key => {
      if (typeof deps?.[key] === 'function') {
        return deps[key].toString()
      }
      return `const ${key} = ${JSON.stringify(deps?.[key])};`
    })
    .join('\n\n')

  return new Promise((resolve, reject) => {
    const blob = new Blob(
      [
        `
      ${dependencies || ''}

      onmessage = function(e) {
        const taskResult = (${task.toString()})();
        postMessage(taskResult);
      };
    `,
      ],
      { type: 'application/javascript' },
    )

    const worker = new Worker(URL.createObjectURL(blob))
    worker.postMessage('')

    worker.onmessage = (e: any) => {
      resolve(e.data)
      worker.terminate()
    }

    worker.onerror = (err: unknown) => {
      reject(err)
      worker.terminate()
    }
  })
}

example:

 import { executeTaskByWorker } from './utils'

 const sendWorker = (data: any) => {
    const taskDepData = data || []
    
    const deps = {
      taskDepData,
    }

    executeTaskByWorker(() => {
      const options = taskDepData.map(item => {
        //... 使用 Web Worker 执行耗时任务
        return {
          ...item,
          label: item.label,
          value: item.id,
        }
      })
      return options
    }, deps).then((res: any) => {
      console.log("🚀 ~ executeTaskByWorker ~ res:", res)
    })
  }

打包时,会混淆变量名导致依赖参数无法找到,改一下使用方式

export function executeTaskByWorker<T = any>(task: string, deps?: Record<string, any>): Promise<T> {
  const dependencies = Object.keys(deps || {})
    .map(key => {
      if (typeof deps?.[key] === 'function') {
        return deps[key].toString()
      }
      return `const ${key} = ${JSON.stringify(deps?.[key])};`
    })
    .join('\n\n')

  return new Promise((resolve, reject) => {
    const blob = new Blob(
      [
        `
      ${dependencies || ''}

      onmessage = function(e) {
        const taskResult = (${task})();
        postMessage(taskResult);
      };
    `,
      ],
      { type: 'application/javascript' },
    )

    const worker = new Worker(URL.createObjectURL(blob))
    worker.postMessage('')

    worker.onmessage = (e: any) => {
      resolve(e.data)
      worker.terminate()
    }

    worker.onerror = (err: unknown) => {
      reject(err)
      worker.terminate()
    }
  })
}

example:

 import { executeTaskByWorker } from './utils'

 const sendWorker = (data: any) => {
    const taskDepData = data || []
    
    const deps = {
      taskDepData,
    }
    const task = `() => {
      const options = taskDepData.map(item => {
        //... 使用 Web Worker 执行耗时任务
        return {
          ...item,
          label: item.label,
          value: item.id,
        }
      })
      return options
    }`

    executeTaskByWorker(task, deps).then((res: any) => {
      console.log("🚀 ~ executeTaskByWorker ~ res:", res)
    })
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 持续分享第2053天 再谈认真和敷衍!一场期待已久的活动,个人感受上有一些些的不完美,尽管多人反馈效果不错,细思量...
    殊梵阅读 44评论 0 0
  • Java面向对象的体系
    程_90ec阅读 431评论 0 0
  • 凌晨五点多,饿。 今天是9月12日,农历八月初十,星期四。 简单梳理一下已经过去的昨天。 ①英语:背诵新单词10个...
    还有力气追逐梦想吗阅读 702评论 0 2
  • “一诺千金,言出必行”是一种非常可贵的品德和行为准则。 “一诺千金”意思是许下的一个诺言有千金的价值。常用来形容一...
    稳重的蒲公英阅读 669评论 0 1
  • 我想,很喜欢沙俄时期风景油画,它那彪悍租框的笔触,真的太美了,真的!
    青牛523_6813阅读 760评论 0 0