2016-12-03 30 views
0

我创建了一个处理大量数据的web worker。下面是代码实现:如何处理对同一Web Worker的多个请求

worker.js

self.addEventListener('message', function(e) { 
    console.log('Message received from main script'); 
    for(var i=0; i<999999999; i++){ 
    // computation here 
    } 
    console.log('Posting message back to main script'); 
    self.postMessage('You said: ' + e.data); 
}, false); 

主要脚本

var myWorker; 
if (window.Worker) { 
    if(typeof(w)=="undefined"){ 
    myWorker = new Worker("scripts/controllers/workers.js"); 
    } 
} 
myWorker.addEventListener('message', function(e) { 
    console.log('Message received from worker'+ e.data); 
}, false); 

function callWorker(someData){ 
    myWorker.postMessage(someData); 
} 
callWorker(someData);//first time call - by user click 
callWorker(someOtherData);//second time call - again user click (don't want to disable button) 

在这种情况下,我不希望执行callWorker多次。 我想要的是,如果callWorker当前正在执行,并且意味着第二个请求提出callWorker,那么第一个请求应该终止,第二个请求应该处理(最近的请求应该处理)。

我该如何做到这一点?感谢您的帮助

回答

1

您可以尝试终止工作人员并重新启动它,我想。 当您调用terminate方法时,它将立即终止而不等待操作完成。

myWorker.terminate(); 
myWorker = new Worker('worker.js'); 
1

如果callWorker当前正在执行和平均,而第二请求提高对callWorker,那么第一请求应终止和第二请求应处理(最新请求应处理)。

如果不终止工作人员,恐怕你无法做到这一点。不要试图终止当前的流程,我认为你应该等到它完成后再发送下一条消息。

0

我有点迟到了这里,但我只是想分享我的解决方案:

我有同样的问题,在我的情况下,等待的时间太长,并创建一个新的工作效率不高足够。

我的解决办法是:

  1. 在增量工人执行任务。
  2. 回到主线程并“询问”是否应该继续。
  3. 主线程回应一个标志,指示我们的工作人员是否应该继续当前任务,或者是否应该用新数据中断/重新开始。

工人代码:

self.addEventListener("message", function (e) { 

    var args = new Int16Array(e.data); 

    if (args[0] === 1) {//Start new task/start over. 

     ExecuteTask(args); 
     self.postMessage("CONTINUE?"); 

    }else if (args[0] === 2) {//Continue 

     ExecuteTask(args); 
     self.postMessage("CONTINUE?"); 
    }else{ 
     self.postMessage("TASK_TERMINATED"); 
    } 
} 

主线程:

myWorker.addEventListener('message', function (e) { 
    if (e.data === "CONTINUE?") { 

     // ask the worker to start over with new data 
     if (newTask) { 
      myWorker.postMessage(newDataMessage); 
     } 
     //No new tasks. Let the worker know it can continue. 
     else{ 
      myWorker.postMessage(continueMessage); 
     } 
    } else if (e.data === "TASK_EXECUTED" || e.data === "TASK_TERMINATED" ) { 
     workerIdle = true; //let main thread know it can execute the next new task instead of queueing it up. 
    }     
});