将require.js与网络工作者一起使用的正确方法是什么?

时间:2016-04-25 12:17:14

标签: javascript three.js requirejs web-worker

目前,我正在努力将现有的网络应用移植到require.js。大多数事情似乎都有效,但使用网络工作者的功能。例如,我有一个工人,在一个单独的js文件MeshLoader.js中定义,它从STL文件加载一个3D模型:

importScripts('../lib/three.min.js', '../lib/STLLoader.js');

onmessage = function(e) {
    var blob = e.data;
    var reader = new FileReaderSync();
    readContents(reader.readAsArrayBuffer(blob));
};

function readContents(contents) {
    try {
        var geometry = new THREE.STLLoader().parse(contents);
    } catch (e) {
        // error handling
    }

    var attributes = {};
    // parsing the file is going on here
    // ...

    postMessage({
            status: 'completed',
            attributes: attributes,
    });
}

一个小注释:STLLoader.js模块是一个three.js插件,用于定义STLLoader对象并将其添加到THREE命名空间。这就是我用require.js重写它的方式:

importScripts('../lib/require.min.js');

require({
    baseUrl: '../lib'
}, [
    'require', 'three.min', 'stlloader'
],
function(require, THREE, STLLoader) {
    onmessage = function(e) {
        var blob = e.data;
        var reader = new FileReaderSync();
        readContents(reader.readAsArrayBuffer(blob));
    };

    function readContents(contents) {
        try {
            var geometry = new THREE.STLLoader().parse(contents);
        } catch (e) {
            // error handling
        }

        var attributes = {};
        // same code as in the initial version
        // ...

        postMessage({
            status: 'completed',
            attributes: attributes,
        });
    }

    return onmessage;
});

通过以下方式调用该工作人员:

var worker = new Worker('js/workers/MeshLoader.js');
worker.postMessage(blob);
worker.onmessage = function (event) {
    if (event.data.status == 'completed') {
        // ...
    } else if (event.data.status == 'failed') {
       // ...
    } else if (event.data.status == 'working') {
       // ...
    }
};

所以,问题是工作人员似乎根本没有被召唤。也许我需要将它声明为requirejs.config()部分中的模块,然后将该模块作为依赖项添加到调用此worker的其他模块中?

1 个答案:

答案 0 :(得分:3)

我像这样使用它(jsfiddle):

importScripts("require.js");
requirejs.config({
    //Lib path
    baseUrl: '.',
    // Some specific paths or alternative CDN's
    paths: {
        "socket.io": [
            "//cdn.socket.io/socket.io-1.3.7",
            "socket.io.backup"]
    },
    waitSeconds: 20
});


requirejs(["LibName"], (TheLibrary) = > {
  // code after all is loaded
  self.onmessage = (msg)=>{
    // do stuff
    TheLibrary.doStuff(msg.data);
  }
  // I tend to dispatch some message here
  self.postMessage("worker_loaded");
}

请注意,只有在您收到"worker_loaded" 后才能可以向工作人员发送消息,因为只有这样才能接受消息。之前,onmessage回调尚未确定。所以你的主要代码应该是:

var worker = new Worker("myworker.js");
worker.onmessage = function(e) {
  if(e.data=="worker_loaded") { 
    // Tell worker to do some stuff
  }
}