美文网首页
Web Worker简单封装 - 2024-09-12

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

作者: 勇敢的小拽马 | 来源:发表于2024-09-11 19:43 被阅读0次
    /**
     * 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)
        })
      }
    

    相关文章

      网友评论

          本文标题:Web Worker简单封装 - 2024-09-12

          本文链接:https://www.haomeiwen.com/subject/fpppljtx.html