我想在网络工作者中使用WebAssembly。
从我的主应用程序中,我这样启动它:
let w = new Worker('test.js');
w.onmessage = (event) => { console.log(event); };
w.onerror = (event) => { console.error(event); };
w.postMessage({ message: "Hello World" });
然后,我创建了一个文件test.js
,如下所示:
self.Module = {
locateFile: function (s) {
console.log(s);
return s;
}
};
self.importScripts("main.js");
// note: `main.js` is the JavaScript glue file created by emcc
self.onmessage = function(messageEvent) {
console.log(messageEvent); // works!
console.log(self.Module); // works!
console.log(self.Module.ccall("test")); // crashes!
}
我收到错误:Uncaught TypeError: Cannot read property 'apply' of undefined
。我不明白为什么self.Module
未定义,这怎么可能?
我觉得Web工作者和WebAssembly的范围有些不能很好地协同工作。
感谢您的投入!
答案 0 :(得分:1)
问题是console.log()在执行时没有显示对象的真实状态。进一步的挖掘表明事实上对象Module
还没有准备好。
我引用:https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html
如何判断页面何时完全加载并且可以安全地调用已编译的函数?
可以在页面完全加载之前调用已编译的函数 在错误中,如果函数依赖于可能不存在的文件
[...]
另一个选择是定义一个 onRuntimeInitialized函数:
Module['onRuntimeInitialized'] = function() { ... };
当运行时准备就绪时,将调用该方法,并且可以调用已编译的代码。
调整我的test.js
(工作人员)文件可以解决问题:
self.Module = {
locateFile: function (s) {
console.log(s);
return s;
}
// Add this function
onRuntimeInitialized: function() {
test();
}
};
self.importScripts("main.js");
// note: `main.js` is the JavaScript glue file created by emcc
self.data = {};
// to pass data from the main JS file
self.onmessage = function(messageEvent) {
console.log(messageEvent); // works!
self.data = messageEvent; // save the data
}
// gets executed when everything is ready.
self.test = function() {
// we may safely use self.data and self.Module now!
console.log(self.Module.ccall("test")); // works!
}