是否可以编写Web工作者来响应两个不同的事件?
我有一个工作人员通过取出相应的法线,位置,索引数组信息并将其作为数组缓冲区传递,从各种.json文件加载缓冲区。然后主线程根据来自worker的'message'事件来获取它。几何图形完美地加载。
由于我缺乏经验,困难在于如何将xhr请求的进度从工作者传递回主线程?如果我追加progress属性,则只传递100%。
有没有办法创建'progress'事件监听器,当这个progress事件触发时,将其发送到main?
我确实发送了缓冲区数组,我能够正确地构建和渲染场景中的网格物体。我希望数据的进度能够流式传输,但我只能得到100.除了100以外的数字来自控制台日志。
我希望将xhr req的进度从工作人员发送到main,但是无法弄明白。
网络工作者摘录:
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
});
答案 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;
}
});