2016-12-03 116 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. 
    }     
});