使用Web程序集的Web worker出错

时间:2018-06-08 00:41:48

标签: javascript c emscripten webassembly

我想在网络工作者中使用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的范围有些不能很好地协同工作。

感谢您的投入!

1 个答案:

答案 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!
}