在 worker.addEventListener 中发送另一个 postMessage

Sending another postMessage in worker.addEventListener

主要问题:从 worker.addEventListener 调用 worker.postMessage 不好吗?下面的示例,我尽量保持它尽可能短。

我有一个带有工作程序的 GWT 本机函数(工作程序之前已初始化,因此我可以重用它。另外,大括号应该是 /*-{}-*/ 但为了语法突出显示我只需使用 {}).

private native void nativeWorkerCalls(JavaScriptObject worker, int cwidth, int cheight) {
    console.log('Main: Pre draw');
    worker.postMessage({'cmd' : 'draw', 'args' : [cwidth*cheight] });
    
    worker.addEventListener('message', function(e) {
        switch (e.data.cmd) {
            case 'draw':
                /* do some stuff */
                console.log('Main: Pre clear');
                worker.postMessage({'cmd' : 'clearBuffer', 'args' : [e.data.offset]}); // I call the worker again!
                break;
            case 'clearBuffer':
                console.log("%c Main: Post clear", 'background: #222; color: #00ffae');
                break;
            default:
                break;
        };
        console.log("Main: ### Finished listener ###");
    }, false);
};

和下面的 worker.js 脚本应该根据传递的 'cmd' 执行不同的切换情况。

importScripts("emscripten.js");

self.addEventListener('message', function(e) {
    var data = e.data;
    switch (data.cmd) {
        case 'draw':
            /* assign some buffer, draw into it */
            self.postMessage({ 'cmd' : 'draw', buffer : mb, offset : buffer});
            break;
        case 'clearBuffer':
            /* clear buffer */
            console.log('Main: Pre clear');
            self.postMessage({'cmd' : 'clearBuffer'});
            break;
        default:
            self.postMessage(null);
        };
}, false);

问题:我第一次运行本机函数一切正常。但是接下来的每个调用都有副作用,即 worker.js 中的事件监听器被重复调用。

一个 运行 应该进行以下调用:

Main: Pre draw

Worker: Draw

Main: Post draw

Main: Pre clear

Main: ### Finished listener ###

Worker: Free buffer

Main: Post clear

Main: ### Finished listener ###

第二次按下按钮给我太多的调用 - 它添加了另一个平局(它似乎没有做任何事情)并且还添加了另一个清除(运行s 进入错误,因为工作人员然后将尝试释放一个已经被释放的缓冲区):

Main: Pre draw

Worker: Draw

Main: Post draw

Main: Pre clear

Main: ### Finished listener ###

Main: Post draw

Main: Pre clear

Main: ### Finished listener ###

Worker: Free buffer

Main: Post clear

Main: ### Finished listener ###

Main: Post clear

Main: ### Finished listener ###

Worker: Free buffer

是的,这很糟糕,任何消息传递系统中的三向往返都是反模式,除了协议发现之类的东西。

为避免这种情况,请将您的状态集中在主线程中,并立即发送包括派生数据在内的所有数据。

代表我的愚蠢错误。我之所以有这些额外的电话,是因为我不断地向工作人员添加事件监听器。显然我需要在我实例化工作人员的地方添加事件侦听器,然后我可以传递工作人员。