1

So I am thinking of creating this app which uses this web worker that i found which generates rubik's cube scrambles (it's actually a bit of an intensive process to generate a random state scramble, especially for bigger cubes, so web workers are necessary for this scenario). And i am wondering if it would be possible to access this web worker from inside a vue component (would there be any issues with serving the worker file or accessing it. If it is possible, how would i make it work?

1 Answers1

3

Yes, you can, here is a demo:

Vue.component('my-component', {
  template: '#my-component',
  data() {
    return {
      cube: '-- no data yet --',
      worker: null
    };
  },
  created() {
    this.initWorker();
  },
  beforeDestroy() {
    this.destroyWorker();
  },
  methods: {
    initWorker() {
      // Here, just for this demo to work, I'm not using an external file
      // for the worker. Instead, I use a Blob. It's still a real Worker!
      // See https://stackoverflow.com/a/6454685/1913729
      const scriptBlob = new Blob(
        [ document.querySelector('#worker-script').textContent ],
        { type: "text/javascript" }
      );
      this.worker = new Worker(window.URL.createObjectURL(scriptBlob));
      this.worker.onmessage = e => this.onCubeReady(e.data);
    },
    destroyWorker() {
      this.worker.terminate();
    },
    scrambleCube() {
      this.cube = '-- Scrambling cube... --'
      this.worker.postMessage('Gimme a cube');
    },
    onCubeReady(cube) {
      this.cube = cube;
    }
  }
});

var vm = new Vue({
  el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.min.js"></script>

<div id="app">
  <my-component></my-component>
</div>

<template id="my-component">
  <div>
    <button @click="scrambleCube">Scramble cube</button>
    <pre>{{cube}}</pre>
  </div>
</template>

<!-- This is just for the demo, and won't be parsed
     because of type="javascript/worker".
     we load it into a Blob to make it a worker -->
<script type="javascript/worker" id="worker-script">
self.addEventListener("message", onMessageReceive);

function onMessageReceive(e) {
  console.log(`Worker received a message`);
  const res = heavyProcessing();
  self.postMessage(res);
}

function heavyProcessing() {
  const endTime = Date.now() + 2000;
  while (Date.now() < endTime) {}
  return 'CUBE MADE BY A WORKER';
}
</script>
blex
  • 22,377
  • 5
  • 35
  • 65
  • I already sort of went ahead with the thing and just put a function that calls a web worker in another file to make it cleaner, but thanks for the help. It's all working well so far. – Jawad Ahmed Jun 22 '20 at 07:04
  • I actually made a speedcubing timer that uses indexeddb to store times for each type of puzzle not that you would care since you're not a cuber but [here](https://cube-timer-concept.herokuapp.com) It's a concept for a full-stack site i intend to make soon. – Jawad Ahmed Jul 14 '20 at 16:51