在worker.addEventListener

时间:2017-02-10 16:16:48

标签: javascript web-worker

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

我有一个工作者的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中的eventlistener会被重复调用。

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

  

主要:预先抽奖

     

工人:画画

     

主要:张贴后

     

主要:预先清除

     

Main:### Finished listener ###

     

工人:免费缓冲区

     

主要:发布清晰

     

Main:### Finished listener ###

第二次按下按钮会给我太多的电话 - 它会增加另一个画面(似乎什么都不做),还会添加另一个画面(因为工作人员会尝试释放缓冲区而导致错误)已经被释放了):

  

主要:预先抽奖

     

工人:画画

     

主要:张贴后

     

主要:预先清除

     

Main:### Finished listener ###

     

主要:张贴后

     

主要:预先清除

     

Main:### Finished listener ###

     

工人:免费缓冲区

     

主要:发布清晰

     

Main:### Finished listener ###

     

主要:发布清晰

     

Main:### Finished listener ###

     

工人:免费缓冲区

2 个答案:

答案 0 :(得分:2)

是的,它很糟糕,任何邮件系统中的3路往返都是反模式,除了协议发现之类的东西。

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

答案 1 :(得分:0)

代表我的愚蠢错误。之所以我有这些额外的调用是因为我不断向工作者添加事件监听器。显然我需要添加事件监听器来实例化worker,然后我可以传递worker。