Веб-работники - как они работают? - PullRequest
5 голосов
/ 24 мая 2010

Я пытаюсь понять этот пример :

HTML (основной код):

   <html>  
     <title>Test threads fibonacci</title>  
     <body>  

     <div id="result"></div>  

     <script language="javascript">  

       var worker = new Worker("fibonacci.js");  

       worker.onmessage = function(event) {  
         document.getElementById("result").textContent = event.data;  
         dump("Got: " + event.data + "\n");  
       };  

       worker.onerror = function(error) {  
         dump("Worker error: " + error.message + "\n");  
         throw error;  
       };  

       worker.postMessage("5");  

     </script>  
     </body>  
   </html> 

Javascript (рабочий код):

   var results = [];  

   function resultReceiver(event) {  
     results.push(parseInt(event.data));  
     if (results.length == 2) {  
       postMessage(results[0] + results[1]);  
     }  
   }  

   function errorReceiver(event) {  
     throw event.data;  
   }  

   onmessage = function(event) {  
     var n = parseInt(event.data);  

     if (n == 0 || n == 1) {  
       postMessage(n);  
       return;  
     }  

     for (var i = 1; i <= 2; i++) {  
       var worker = new Worker("fibonacci.js");  
       worker.onmessage = resultReceiver;  
       worker.onerror = errorReceiver;  
       worker.postMessage(n - i);  
     }  
  };  

У меня есть следующие вопросы:

  • Когда именно рабочий код начинает выполняться? Сразу после казни var worker = new Worker("fibonacci.js");?

  • Правда ли, что присвоение onmessage = function(event) { ... } в рабочем коде будет выполнено до worker.postMessage("5"); в основном коде?

  • Может ли рабочий код обращаться к глобальным переменным, которые определены в основном коде (например, worker)?

  • Может ли основной код обращаться к глобальным переменным, которые определены в рабочем коде (например, results)?

  • Мне кажется, что worker.onmessage = function(event) {...} в основном коде имеет то же значение, что и onmessage = function(event) {...} в рабочем коде (который является onmessage обработчиком событий рабочего). Где я не прав? В чем разница между ними?

  • Что этот код должен делать на самом деле? Когда я запускаю его здесь , он просто печатает "5". Это то, что он должен делать, или я что-то упустил?

Большое спасибо!

Ответы [ 2 ]

6 голосов
/ 18 апреля 2011

Ознакомьтесь с HTML5 Rocks: Основы веб-работников для общего учебника.

  • Рабочие начнут работать, как только вы вызовете метод postMessage рабочего.
  • функция, связанная с onmessage работника в основном коде, будет работать, когда работник вызывает postMessage.
  • глобальные переменные не являются общими для основного и рабочего потоков. Единственный способ передачи данных - обмен сообщениями через postMessage.
  • Как вы и подозревали, onmessage для кода работника и основного кода имеет одинаковое значение. Это обработчик события, когда поток получает событие сообщения. Вместо этого вы можете использовать addEventListener, перехватывая событие message:

Основной код:

function showResult(event) {  
   document.getElementById("result").textContent = event.data;  
   dump("Got: " + event.data + "\n");  
}
var worker = new Worker("fibonacci.js");
worker.addEventListener('message', showResult, false);

Рабочий код:

addEventListener('message', resultReceiver, false);

Пример Фибоначчи, который вы взяли, является примером рекурсивного рабочего. Если не использовать рабочих, это было бы что-то вроде этого:

function fibonacci(n) {
    if (n == 0 || n == 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

var result = fibonacci(5);
dump("Got: " + result + "\n");

(о нет, я не собираюсь делать для вас стек без стека. Вы сами пишете!)

0 голосов
/ 10 августа 2013

Я также хочу добавить, что вы можете отлаживать веб-работники только в браузерах на основе Chromium .Вы должны выбрать Источники на панели разработчика и в правом столбце разверните нижнюю строку Рабочие , а затем установите флажок Пауза при запуске .

...