2016-12-03 3 views
0

Ich habe einen Web-Worker erstellt, der große Daten verarbeitet. Folgende sind Code-Implementierung:So behandeln Sie mehrere Anforderungen an denselben 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); 

Haupt Script

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) 

in diesem Fall ich möchte nicht callWorker mehrfach auszuführen. was ich will ist, wenn callWorker wird derzeit ausgeführt und bedeuten, während eine zweite Anfrage für callWorker auslösen, dann sollte die erste Anfrage beendet werden und zweite Anfrage sollte verarbeiten (neueste Anfrage sollte verarbeiten).

Wie kann ich das erreichen? Vielen Dank für Ihre Hilfe

Antwort

1

Sie können versuchen, den Worker zu beenden und neu zu initiieren, denke ich. Wenn Sie die Methode zum Beenden aufrufen, wird sie sofort beendet, ohne dass die Ausführung der Operationen beendet wird.

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

wenn callWorker gerade ausgeführt wird und bedeuten, während eine zweite Anforderung für callWorker erhöhen, dann sollten erste Anfrage beenden und den zweiten Antrag sollte verarbeiten (letzte Anforderung sollte verarbeiten).

Ich fürchte, Sie können dies nicht erreichen, ohne den Arbeiter zu beenden. Anstatt zu versuchen, den laufenden Prozess zu beenden, denke ich, dass du bis zum Ende warten solltest und dann die nächste Nachricht senden solltest.

0

Ich bin ein bisschen spät zur Party hier, aber ich wollte nur meine Lösung teilen:

Ich hatte das gleiche Problem und in meinem Fall Warte würde zu lange dauern und ein neuer Arbeiter zu schaffen nicht effizient war genug.

Meine Lösung war:

  1. die Aufgabe, in den Arbeitern in Schritten auszuführen.
  2. Post zurück zum Haupt-Thread und "fragen", ob es weitergehen soll.
  3. Der Hauptthread antwortet mit einem Flag, das angibt, ob der Worker die aktuelle Aufgabe fortsetzen soll oder ob er mit neuen Daten beginnen soll.

Der Arbeiter Code:

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"); 
    } 
} 

Haupt thread:

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. 
    }     
}); 
Verwandte Themen