Web工作者可以支持多个事件,如消息和进度吗?

时间:2018-03-18 10:51:32

标签: javascript three.js web-worker

是否可以编写Web工作者来响应两个不同的事件?

我有一个工作人员通过取出相应的法线,位置,索引数组信息并将其作为数组缓冲区传递,从各种.json文件加载缓冲区。然后主线程根据来自worker的'message'事件来获取它。几何图形完美地加载。

由于我缺乏经验,困难在于如何将xhr请求的进度从工作者传递回主线程?如果我追加progress属性,则只传递100%。

有没有办法创建'progress'事件监听器,当这个progress事件触发时,将其发送到main?

我确实发送了缓冲区数组,我能够正确地构建和渲染场景中的网格物体。我希望数据的进度能够流式传输,但我只能得到100.除了100以外的数字来自控制台日志。

我希望将xhr req的进度从工作人员发送到main,但是无法弄明白。

enter image description here

网络工作者摘录:

import { BufferGeometryLoader, BufferGeometry } from 'three';


var progress;

const loader = new BufferGeometryLoader();
const geometry = new BufferGeometry();

  /* is this possible? how to get progress info in here to stream over? */
  self.addEventListener('progress', (event) => {
    console.log('event in progress: ', progress);
  });

  self.addEventListener('message', (event) => {
    const { model, part } = event.data;
     loader.load(`https://models/${model}/${part}.json`, (geometry) => {
      // all the code to load the buffergeometry and pass to the main thread
      // removed for sake of focus
      },
      (xhr) => {
       /* how to pass just the value of progress as it happens so i can get a progress bar in the DOM? Or say emit a progress event that this worker can respond to? */
       progress = (xhr.loaded / xhr.total * 100);
       console.log('progress: ', progress);
      },
      (err) => {
        console.log('err: ', err);
      }
    );
  });

主要摘录

    /* If i can capture the progress data, i can easily build a loading progress bar */
    worker.addEventListener('progress', (event) => {
      console.log('event.data: ', event.data);
    });

    worker.addEventListener('message', (event) => {

      // build meshes from buffergeometries and assign materials and add to scene
    });

1 个答案:

答案 0 :(得分:1)

您可以使用message事件执行此操作,传递一个对象,您可以使用属性(可能称为type)区分您正在发送的消息的类型

在您的工作人员中,当您想要使用进度更新主线程时

postMessage({type: "progress", progress: xhr.loaded / xhr.total * 100});

如果要发送数据:

postMessage({type: "data", data: /*...*/});

在main中,您有message的事件处理程序,该事件处理程序在type上发送:

worker.addEventListener('message', (event) => {
    const msg = event.data;
    switch (msg.type) {
        case "progress":
            // ...handle progress message, progress is in `msg.progress`
            break;
        case "data":
            // ...handle data message, data is in `msg.data`
            break;
    }
});

Live Example on plnkr