Skip to content

WebWorker 工作线程

工作线程的引入是为了防止js主线程被阻塞的, 大多数情况下你不需要用到,因为js是异步非阻塞的,只有在主线程涉及到大量计算时你需要用到它。

工作线程在大量计算场景下可以更好地利用多核CPU的性能。

该工具封装了一个更加易于使用的使用方式。

runWorker 基础使用

先看一下以下的基础示例

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
<template>
  <div>单次</div>
  <div>[1, 2, 3, 4]之和为: {{resultOnce}}, 用时{{usedTimeOnce}}ms</div>

  <hr/>

  <div>多次:</div>
  <div><input style="width: 100px; border: 1px solid #eee; padding: 0 4px" v-model="count" /> 个随机数的和为: {{ result }}, 用时{{usedTime}}ms</div>
  <button @click="handleSum" style="color: var(--vp-c-brand)">重新计算</button>
</template>

<script lang="ts" setup>
// 可以使用 import { runWorkerOnce, runWorker } from 'cat-kit'
import { runWorkerOnce, runWorker } from '@cat-kit/fe'
import { shallowRef } from 'vue'

const url = new URL('./sum.js', import.meta.url)

const resultOnce = shallowRef(0)
const usedTimeOnce = shallowRef(0)
let t = Date.now()
runWorkerOnce<number>(url, [1, 2, 3, 4]).then(sum => {
  resultOnce.value = sum
  usedTimeOnce.value  = Date.now() - t
}).catch(err => console.error(err))

const result = shallowRef(0)
const usedTime = shallowRef(0)
let t2 = 0
const count = shallowRef(10)
const worker = runWorker<number>(url, {
  onMessage(data) {
    result.value = data.data
    usedTime.value = Date.now() - t2
  },
  onError(err) {
    console.error(err)
  }
})

const handleSum = () => {
  const randomNumbers = Array.from({ length: count.value }).map(() => {
    return Math.floor(Math.random() * 100)
  })
  t2 = Date.now()
  worker.send(randomNumbers)
}

handleSum()
</script>

可以看到启动工作线程是有代价的, 在以上的示例中, 他甚至比计算本身的耗时还要多得多, 这意味着你如果 在无须大量计算(比如加密)或者IO操作(比如文件读取)的场景下使用会弄巧成拙.

使用场景

WebWorker的使用场景在于你的某个程序是否会阻塞到整个主线程, 当程序运行时你的页面出现操作上的卡顿时(例如滚动,跳转),你就需要考虑到用WebWorker来优化你的程序了。

计算文件的md5

文件md5值一般用于附件的断点续传和秒传,但计算大文件的md5值是相当耗时的, 因此这是一个最常见的使用场景。

base64操作

有时候文件会被转化为base64方便传输,同样的大量数据的base64操作也属于密集计算型操作,因此也可以使用WebWorker。

IndexedBD数据库

文件读取

MIT Licensed