JS Worker多线程

1. 原生JS多线程

页面运行worker,限制了worker.js需要与页面同源。本地js代码可以借助URL.createObjectURL和Data URL的方式规避

1.1 URL.createObjectURL

vue-worker等库一般借助于URL.createObjectURL创建本地js文件的方式规避同源限制.

<script>
  // 1.定义多线程实际运行的函数
  function threadFn(a, b, c) {
    // 可以传递初始化参数,但参数应尽量通过onmessage传递
    console.log('Worker Thread | receive initial args:', a, b, c)

    // worker进程内通过self调用context方法,不能使用this
    self.onmessage = (e) => {
      console.log('Worker Thread | onmessage:', e.data)

      console.log('Worker Thread | postMessage:', e.data)
      self.postMessage(e.data)
    }
  }

  // 2.定义worker创建方法:传入多线程运行函数和初始参数,创建worker
  function createWorker(fn, ...params) {
    // 将多线程函数转字符串
    const fnStr = `(${fn.toString()})(${[...params]})`
    console.warn('Main Thread | thread function string:', fnStr)

    // worker必须使用页面同源的js,此处借助URL.createObjectURL转换
    const blob = new Blob([fnStr])
    const url = URL.createObjectURL(blob)
    // 优化:URL.createObjectURL创建的资源必须手动通过URL.revokeObjectURL释放,否则需要刷新Browser Context时才会被释放

    const worker = new Worker(url)
    return worker
  }

  // 3.实例化worker
  const c = "'c'" // 线程创建传递初始化参数。注意,字符串常量需要两重引号包裹,否则函数转字符串会解析异常。建议通过postMessage传递数据
  let worker = createWorker(threadFn, "'aaa'", c, 111)

  // 4.定义外层worker数据首发
  worker.onmessage = e => {
    console.warn('Main Thread | onmessage:', e.data)

    if (e.data === 'terminate') {
      terminate()
    }
  }

  // 5.向worker发送数据
  console.warn('Main Thread | postMessage:', 'main')
  worker.postMessage('main')

  // 6.注销worker
  function terminate() {
    worker.terminate()
    worker = null
    console.warn('Main Thread | worker has been terminated')
  }

  setTimeout((() => {
    console.warn('Main Thread | postMessage:', 'terminate')
    worker.postMessage('terminate')
  }), 1000)
</script>

1.2 Data URL

除了URL.createObjectURL外,还可以通过Data URL实现。通过Data URL运行的js函数不能省略语句的分号

function threadFn () {
  console.log('worker | init thread');

  self.postMessage('create success');
}

function createWorker(fn) {
  const worker = new Worker(`data:,(${fn.toString()})()`)
  return worker
}

const worker = createWorker(threadFn)
worker.onmessage = e => {
  console.log('main | onmessage', e.data)
}

2. Vue多线程

<template>
  <div>Worker</div>
</template>

<script>
import Vue from 'vue'
import worker from 'vue-worker'

Vue.use(worker)

function test(a, b) {
  return a + b
}

export default {
  created() {
    this.init()
  },
  methods: {
    init() {
      this.runWorker()
      this.createWorker()
    },
    runWorker() {
      let worker = this.$worker.run(test, [1, 2])

      worker.then(res => {
        console.log(`this.$worker`, res)
      })

      worker = null // destroy worker
    },
    createWorker() {
      const actions = [
        { message: 'f1', func: a => a++ },
        { message: 'f2', func: (a, b) => a + b }
      ]
      let workerList = this.$worker.create(actions)

      workerList.postMessage('f1', [99]).then(res => console.log('f1', res))
      workerList.postMessage('f2', [99, 101]).then(res => console.log('f2', res))

      workerList = null // destroy worker
    },
  }
}
</script>
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Vue 3支持Web Worker多线程的特性,这是一种在浏览器中运行JavaScript代码的方式,可以在后台运行独立的线程,提高应用程序性能和响应能力。 在Vue 3中,可以使用`Vue. createApp()`方法创建Vue实例,并使用`createWebWorker`方法将其转换为Web Worker。这个方法接收一个参数,指定Worker脚本的URL或者内联函数的URL。例如: ```javascript const app = Vue.createApp({...}); const worker = app.createWebWorker('path-to-worker-script.js'); ``` 然后,可以使用`worker`对象的方法与Web Worker进行通信。例如,通过`postMessage`方法发送消息给Worker线程: ```javascript worker.postMessage({ data: 'message' }); ``` 同时,还可以通过`onmessage`事件监听来自Worker线程的消息: ```javascript worker.onmessage = function(event) { const data = event.data; // 处理接收到的消息 }; ``` 在Worker线程中,可以使用`self`关键字引用Worker对象,同样可以通过`postMessage`方法发送消息给主线程,并通过`onmessage`事件处理来自主线程的消息。 Web Worker多线程功能可以极大地提高Vue应用程序的性能和响应能力,将一些耗时的操作(如计算、渲染等)放在Worker线程中运行,避免阻塞主线程,提高用户体验。 需要注意的是,在使用Web Worker时,需要考虑到跨域访问的限制,以及数据传输的序列化和反序列化等问题。在实际应用中,需要根据具体需求和场景合理使用Web Worker多线程功能。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值