代码之家  ›  专栏  ›  技术社区  ›  andreas

Web工作进程使用Web程序集时出错

  •  0
  • andreas  · 技术社区  · 8 年前

    我想在web工作者中使用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 回复  |  直到 8 年前
        1
  •  1
  •   andreas    8 年前

    问题是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!
    }