将 require.js 与网络工作者一起使用的正确方法是什么?
What's the right way to use require.js with web-workers?
目前,我正在努力将现有的网络应用程序移植到 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 的其他模块?
我是这样用的(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"
后,您才能 post 向工作人员发送消息,因为只有这样消息才会被接受。之前,onmessage
回调还没有建立。所以你的主要代码应该是:
var worker = new Worker("myworker.js");
worker.onmessage = function(e) {
if(e.data=="worker_loaded") {
// Tell worker to do some stuff
}
}
目前,我正在努力将现有的网络应用程序移植到 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 的其他模块?
我是这样用的(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"
后,您才能 post 向工作人员发送消息,因为只有这样消息才会被接受。之前,onmessage
回调还没有建立。所以你的主要代码应该是:
var worker = new Worker("myworker.js");
worker.onmessage = function(e) {
if(e.data=="worker_loaded") {
// Tell worker to do some stuff
}
}