Пример использования Worker
Worker - технология JS, позволяющая запускать длительные вычисления в фоновом режиме. При этом страница браузера не "подвисает" и лишь время от времени обменивается с Worker-ом сообщениями, через которые передаются данные. Кроме этого, в большинстве браузеров, таймеры на неактивной странице тормозятся, что практически останавливает вычисления. С Worker-ом этого не происходит. Этот шаблон подготовлен для меня, но может оказаться полезным ещё кому-нибудь.
Простой пример
В код страницы вставляем:
let worker = new Worker( "worker_simple.js" ); // создаём Worker-а worker.onmessage = function (e) // принимаем данные от worker { switch (e.data.kind){ // разновидность сообщения case "info" : // переписываемая информация о процессе document.getElementById( "calcID" ).innerHTML = e.data.st; break ; } }; worker.postMessage({kind: 'start' , number:10000000}); // посылаем данные в worker |
Создаём файл "worker_simple.js" в котором помещаем:
'use strict' ; if ( 'function' === typeof importScripts) { // подключаем внешние модули //importScripts('queue.js'); // должны быть, где и worker.js } var workerFinderSolution = new FinderSolution(); /**************************************************************************************** * Функция, получающая сообщения из внешнего управляющего модуля (html-страницы) * e.data - содержит структуру данных, необходимых для вычислений */ onmessage = function (e) { switch (e.data.kind){ // разновидность сообщения case "start" : // начало вычислений workerFinderSolution.number = e.data.number; workerFinderSolution.init (); // инициализируем workerFinderSolution.timer(); // запускаем таймер break ; } } /**************************************************************************************** * */ function FinderSolution() { this .wait = 1; // пауза в ms для получения сообщений this .send = 100; // время в ms для послылки браузеру инфо this .loops = 1000; // число циклов вычислений до паузы } /**************************************************************************************** * Инициализация вычислений */ FinderSolution. prototype .init = function () { this .startTime = new Date(); } /**************************************************************************************** * Условие окончания вычислений */ FinderSolution. prototype .finish = function () { return this .number <= 0; } /**************************************************************************************** * Один шаг вычислений */ FinderSolution. prototype .calc = function () { this .number--; } /**************************************************************************************** * Таймерная функций */ FinderSolution. prototype .timer = function () { for (let i=0; ! this .finish() && i < this .loops; i++) this .calc(); // делаем loops циклов вычислений if (( new Date() - this .startTime) > this .send){ this .startTime = new Date(); postMessage({kind: "info" , st: this .number }); } if (! this .finish()) // вызовем повторно через время wait setTimeout( this .timer.bind( this ), this .wait); else // вычисления окончились: postMessage({kind: "info" , st: "finish" }); } |
Более продвинутый пример
number:
,
Нажми на меня
На html-странице есть два элемента для вывода с id="infoID" и id="outID". Первый служит для вывода частой (но короткой) информации о ходе вычислений (она всё время перетирается). Во второй, время от времени, добавляются промежуточные результаты вычислений. Запуск вычислений осуществляется нажатием кнопки run. Ею же можно вычисления прервать.
В данном примере число из поля редактирования передаётся в Worker. Там оно постоянно уменьшает на 1, пока не получит 0. Собственно вычисления находятся в модуле worker.js. Таймер на html-странице служит лишь для периодического запроса информации о ходе вычислений. Как страница, так и модуль worker.js подробно задокументированы, поэтому, для дальнейшего изучения технологии стоит переместиться в код.
Важное замечание. Если работа с Worker-ами происходит локально в Chrome, то необходимо закрыть все браузеры и запустить Chrome с ключом: --allow-file-access-from-files