Skip to content
On this page

useWorker

The WebWorker.

Parameters

typescript
import { useWorker } from '@elonehoo/pistachio'

useWorker(stringUrl, args?, options?)
import { useWorker } from '@elonehoo/pistachio'

useWorker(stringUrl, args?, options?)
ParametersTypeRequiredDefaultDescription
stringUrlString|URLtrueWebworker file path
argsany|any[]falseundefinedarguments for the first message sent to the worker
optionsOptionsfalseundefinedDocumentation

State

The useWorker function exposes the following reactive state:

typescript
import { useWorker } from '@elonehoo/pistachio'

const { worker, data, terminated, errorEvent, errored } = useWorker()
import { useWorker } from '@elonehoo/pistachio'

const { worker, data, terminated, errorEvent, errored } = useWorker()
StateTypeDescription
workerWorkerWorker instance
dataRef<any>Last message received by the worker
terminatedRef<boolean>Has worker being terminated
errorEventRef<any>Last event received on 'error' message
erroredRef<boolean>Has error occurred

Methods

The useWorker function exposes the following methods:

typescript
import { useWorker } from '@elonehoo/pistachio'

const { postMessage, terminate } = useWorker()
import { useWorker } from '@elonehoo/pistachio'

const { postMessage, terminate } = useWorker()
SignatureDescription
postMessagePostMessage to the worker
terminateTerminates the worker

Inside the worker

Inside of worker you can use the exposeWorker, it will post the result and execute the method when receiving the message.

typescript
// super.worker.js
import { useWorker } from '@elonehoo/pistachio'

const max = numbers => Math.max(...numbers)

exposeWorker(max)
// super.worker.js
import { useWorker } from '@elonehoo/pistachio'

const max = numbers => Math.max(...numbers)

exposeWorker(max)

TIP

exposeWorker you can use yield to sending a stream of data to the main thread

Example

Sort

time: 1679286348479

The worker can take more than 10 seconds to finish, the timer shouldn't stop while the worker is processing

Numbers: []... []

vue
<script setup lang="ts">
import { computed, defineComponent, ref, watch, watchEffect } from 'vue'
import { exposeWorker, useDate, useWorker } from '@elonehoo/pistachio'

const timeout = ref(1500)
const { now } = useDate({ refreshMs: 10 })
const numbers = [...Array(50000)].map(() =>
  Math.floor(Math.random() * 1000000)
)
const sortedNumbers = ref([])
const firstSegment = computed(() => sortedNumbers.value.slice(0, 10))
const lastSegment = computed(() => sortedNumbers.value.slice(-10))
const { postMessage, data, errored, errorEvent } = useWorker(
  '/worker.example.js'
)
watch(
  data,
  (d) => {
    sortedNumbers.value = d
  },
  { lazy: true }
)
watch(
  errorEvent,
  (e) => {
    sortedNumbers.value = ['error', e.returnValue]
  },
  { lazy: true }
)
const sortWorker = () => {
  postMessage(numbers)
}
</script>

<template>
  <div>
    <h3>Sort</h3>
    <p>time: {{ now }}</p>
    <h6>
      The worker can take more than 10 seconds to finish, the timer shouldn't
      stop while the worker is processing
    </h6>

    <p>
      Numbers:
      <b>{{ firstSegment }}</b>...
      <b>{{ lastSegment }}</b>
    </p>

    <ul>
      <li>
        <button @click="sortWorker">
          Worker
        </button>
        <p v-if="errored" :style="{ color: 'red' }">
          {{ errorEvent }}
        </p>
      </li>
    </ul>
  </div>
</template>
<script setup lang="ts">
import { computed, defineComponent, ref, watch, watchEffect } from 'vue'
import { exposeWorker, useDate, useWorker } from '@elonehoo/pistachio'

const timeout = ref(1500)
const { now } = useDate({ refreshMs: 10 })
const numbers = [...Array(50000)].map(() =>
  Math.floor(Math.random() * 1000000)
)
const sortedNumbers = ref([])
const firstSegment = computed(() => sortedNumbers.value.slice(0, 10))
const lastSegment = computed(() => sortedNumbers.value.slice(-10))
const { postMessage, data, errored, errorEvent } = useWorker(
  '/worker.example.js'
)
watch(
  data,
  (d) => {
    sortedNumbers.value = d
  },
  { lazy: true }
)
watch(
  errorEvent,
  (e) => {
    sortedNumbers.value = ['error', e.returnValue]
  },
  { lazy: true }
)
const sortWorker = () => {
  postMessage(numbers)
}
</script>

<template>
  <div>
    <h3>Sort</h3>
    <p>time: {{ now }}</p>
    <h6>
      The worker can take more than 10 seconds to finish, the timer shouldn't
      stop while the worker is processing
    </h6>

    <p>
      Numbers:
      <b>{{ firstSegment }}</b>...
      <b>{{ lastSegment }}</b>
    </p>

    <ul>
      <li>
        <button @click="sortWorker">
          Worker
        </button>
        <p v-if="errored" :style="{ color: 'red' }">
          {{ errorEvent }}
        </p>
      </li>
    </ul>
  </div>
</template>

Released under the MIT License.