diff options
Diffstat (limited to 'files/ru/dom/using_web_workers/index.html')
-rw-r--r-- | files/ru/dom/using_web_workers/index.html | 871 |
1 files changed, 0 insertions, 871 deletions
diff --git a/files/ru/dom/using_web_workers/index.html b/files/ru/dom/using_web_workers/index.html deleted file mode 100644 index 7503eccacb..0000000000 --- a/files/ru/dom/using_web_workers/index.html +++ /dev/null @@ -1,871 +0,0 @@ ---- -title: Использование Web Workers -slug: DOM/Using_web_workers -tags: - - воркер - - поток -translation_of: Web/API/Web_Workers_API/Using_web_workers ---- -<div>{{DefaultAPISidebar("Web Workers API")}}</div> - -<p>Web Worker-ы предоставляют простое средство для запуска скриптов в фоновом потоке. Поток Worker'а может выполнять задачи без вмешательства в пользовательский интерфейс. К тому же, они могут осуществлять ввод/вывод, используя <code><a class="internal" href="/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequest">XMLHttpRequest</a></code> (хотя атрибуты <code>responseXML</code> и <code>channel</code> всегда будут равны null). Существующий Worker может отсылать сообщения JavaScript коду-создателю через обработчик событий, указанный этим кодом (и наоборот). Эта статья дает детальную инструкцию по использованию Web Workers.</p> - -<h2 id="Web_Workers_API">Web Workers API</h2> - -<p>Worker - это объект, создаваемый конструктором (например, {{domxref("Worker.Worker", "Worker()")}}) и запускающий именной JavaScript файл — этот файл содержит код, который будет выполнен в потоке Worker'а; объекты же Workers запускаются в другом глобальном контексте, отличающемся от текущего, - {{domxref("window")}}. Поэтому использование переменной {{domxref("window")}} для получения текущего глобального контекста (вместо {{domxref("window.self","self")}}) внутри {{domxref("Worker")}} вернет ошибку.</p> - -<p>Контекст Worker'а представлен объектом {{domxref("DedicatedWorkerGlobalScope")}} в случае выделенных Workers (обычные Workers используются одним скриптом; совместные Workers используют объект {{domxref("SharedWorkerGlobalScope")}}). Выделенный Worker доступен только из скрипта-родителя, в то время как совместные Workers могут быть доступны из нескольких сценариев.</p> - -<div class="note"> -<p><strong>Заметка</strong>: Смотрите <a href="/en-US/docs/Web/API/Web_Workers_API">страницу Web Workers API</a> для справки по Workers и прочие руководства.</p> -</div> - -<p>Вы можете запускать любой код внутри потока worker-а, за некоторыми исключениями. Например, вы не можете прямо манипулировать DOM внутри worker-а, или использовать некоторые методы по умолчанию и свойства объекта {{domxref("window")}}. Но вы можете использовать большой набор опций, доступный под <code>Window</code>, включая <a href="/en-US/docs/Web/API/WebSockets_API">WebSockets</a>, и механизмы хранения данных, таких как <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB</a> и относящихся только к Firefox OS <a href="/en-US/docs/Web/API/Data_Store_API">Data Store API</a>. Для дополнительной информации смотрите <a href="/en-US/docs/Web/API/Worker/Functions_and_classes_available_to_workers">Functions and classes available to workers</a>.</p> - -<p>Данные передаются между worker-ами и главным потоком через систему сообщений — обе стороны передают свои сообщения, используя метод <code>postMessage()</code> и отвечают на сообщения при помощи обработчика событий <code>onmessage</code> (сообщение хранится в аттрибуте data события {{event("Message")}}). Данные при этом копируются, а не делятся.</p> - -<p>Объекты Workers могут, в свою очередь, создавать новые объекты workers, и так до тех пор, пока всё работает в рамках текущей страницы. Плюс к этому, объекты workers могут использовать <a class="internal" href="/en-US/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code></a> для сетевого ввода/вывода, но есть исключение - атрибуты <code>responseXML</code> и <code>channel</code> объекта <code>XMLHttpRequest</code> всегда возвращают <code>null</code>.</p> - -<h2 id="Выделенные_Workers">Выделенные Workers</h2> - -<p>Как уже упоминалось выше, выделенный Worker доступен только для скрипта, который его вызвал. В этом разделе речь пойдет о JavaScript, который можно найти в нашем <a class="external external-icon" href="https://github.com/mdn/simple-web-worker">основном примере выделенного Worker</a> (<a class="external external-icon" href="http://mdn.github.io/simple-web-worker/">запустить скрипт</a>): этот пример позволяет ввести два числа для умножения. Эти числа отправляются в Worker, перемножаются, а результат возвращается на страницу и отображается.</p> - -<p>Этот пример достаточно тривиален, но для ознакомления с базовыми концепциями worker-ов мы решили его упростить. Более продвинутые детали описаны далее в статье.</p> - -<h3 id="Определение_поддержки_Worker">Определение поддержки Worker</h3> - -<p>Для большего контроля над ошибками и обратной совместимости, рекомендуется обернуть ваш код доступа к worker-у в следующий (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/main.js">main.js</a>):</p> - -<pre class="brush: js notranslate">if (window.Worker) { - - ... - -}</pre> - -<h3 id="Создание_выделенного_worker">Создание выделенного worker</h3> - -<p>Создание нового worker-а — это легко. Всё что вам нужно это вызвать конструктор {{domxref("Worker.Worker", "Worker()")}}, указав URI скрипта для выполнения в потоке worker-а (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/main.js">main.js</a>):</p> - -<div style="overflow: hidden;"> -<pre class="brush: js notranslate">var myWorker = new Worker("worker.js"); -</pre> -</div> - -<h3 id="Передача_сообщений_в_и_из_выделенного_worker">Передача сообщений в и из выделенного worker</h3> - -<p>Магия worker-ов происходит через {{domxref("Worker.postMessage", "postMessage()")}} метод и обработчик событий {{domxref("Worker.onmessage", "onmessage")}}. Когда вы хотите отправить сообщение в worker, вы доставляете сообщение к нему вот так (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/main.js">main.js</a>):</p> - -<pre class="brush: js notranslate">first.onchange = function() { - myWorker.postMessage([first.value,second.value]); - console.log('Message posted to worker'); -} - -second.onchange = function() { - myWorker.postMessage([first.value,second.value]); - console.log('Message posted to worker'); -}</pre> - -<p>В приведенном фрагменте кода мы имеем два {{htmlelement("input")}} элемента, представленных переменными <code>first</code> и <code>second</code>; когда значение любой из переменных изменяется,<code> myWorker.postMessage([first.value,second.value])</code> используется для отправки обоих значений, представленных в виде массива, в worker. Посредством аргумента <code>message</code> возможна передача практически любых данных в worker.</p> - -<p>Внутри worker-a мы можем обрабатывать сообщения и отвечать на них при помощи добавления обработчика события <code>onmessage</code> подобным образом (<a href="https://github.com/mdn/simple-web-worker/blob/gh-pages/worker.js">worker.js</a>):</p> - -<pre class="brush: js notranslate">onmessage = function(e) { - console.log('Message received from main script'); - var workerResult = 'Result: ' + (e.data[0] * e.data[1]); - console.log('Posting message back to main script'); - postMessage(workerResult); -}</pre> - -<p>Обработчик <code>onmessage</code> позволяет нам запустить некий код всякий раз, когда получен пакет с сообщением, доступным в атрибуте <code>data</code> события <code>message</code>. В примере выше мы просто перемножаем вместе две цифры, после чего используем <code>postMessage()</code> снова, чтобы отправить полученный результат назад в основной поток.</p> - -<p>Возвращаясь в основной поток, мы используем <code>onmessage</code> снова, чтобы отреагировать на сообщение, отправленное нам назад из worker-а:</p> - -<pre class="brush: js notranslate">myWorker.onmessage = function(e) { - result.textContent = e.data; - console.log('Message received from worker'); -}</pre> - -<p>В примере выше мы берём данные из события сообщения и ставим их как <code>textContent</code> у результирующего абзаца, чтобы показать пользователю результат этой калькуляции.</p> - -<p class="note"><strong>Заметка</strong>: Обратите внимание, что <font face="consolas, Liberation Mono, courier, monospace"><code>onmessage()</code> и <code>postmessage()</code> должны вызываться из экземпляра Worker в главном потоке, но не в потоке worker-а. Это связано с тем, что внутри потока worker-а, worker выступает в качестве глобального объекта.</font></p> - -<p class="note"><strong>Заметка</strong>: При передаче сообщения между основным потоком и потоком worker-а, оно копируется или "передается" (перемещается), не делится между потоками. Читайте {{anch("Transferring data to and from workers: further details")}} для более подробного объяснения.</p> - -<h3 id="Завершение_работы_worker-а">Завершение работы worker-а</h3> - -<p>Прекращение работы worker-а главного потока достигается методом {{domxref("Worker", "terminate")}}:</p> - -<pre class="brush: js notranslate">myWorker.terminate();</pre> - -<p>Поток worker-а немедленно уничтожается.</p> - -<h3 id="Обработка_ошибок">Обработка ошибок</h3> - -<p>При ошибке во время выполнения worker-а, вызывается его обработчик событий <code>onerror</code>. Он принимает событие <code>error</code>, которое реализует интерфейс <code>ErrorEvent</code>.</p> - -<p>Событие не всплывает и его можно отменить. Для отмены действия по умолчанию, worker может вызвать метод <a class="internal" href="/en-US/docs/Web/API/Event/preventDefault"> <code>preventDefault()</code> </a> в обработчике события ошибки.</p> - -<p>У события ошибки есть три поля, которые представляют интерес:</p> - -<dl> - <dt><code>message</code></dt> - <dd>Сообщение об ошибке в читаемом виде.</dd> - <dt><code>filename</code></dt> - <dd>Имя файла со скриптом, в котором ошибка произошла.</dd> - <dt><code>lineno</code></dt> - <dd>Номер строки в файле, в котором произошла ошибка.</dd> -</dl> - -<h3 id="Создание_subworkers">Создание subworkers</h3> - -<p>Worker-ы могут запускать другие worker-ы. Так называемые sub-worker'ы должны быть того же происхождения (same-origin), что и родительский документ. Кроме того, URI для subworker-ов рассчитываются относительно родительского worker'а, а не родительского документа. Это позволяет worker-ам проще следить за тем, где находятся их зависимости.</p> - -<h3 id="Импорт_скриптов_и_библиотек">Импорт скриптов и библиотек</h3> - -<p>Worker потоки имеют доступ к глобальной функции, <code>importScripts()</code>, которая позволяет импортировать скрипты с того же домена в их область видимости. Функция принимает ноль и более URI параметров, как список ссылок на ресурсы для импорта; все нижеприведенные примеры верны:</p> - -<pre class="brush: js notranslate">importScripts(); /* imports nothing */ -importScripts('foo.js'); /* imports just "foo.js" */ -importScripts('foo.js', 'bar.js'); /* imports two scripts */ -</pre> - -<p>Браузер загружает каждый указанный скрипт и исполняет его. Любые глобальные объекты, создаваемые каждым скриптом могут быть использованы в worker'е. Если скрипт не удалось загрузить, будет брошена ошибка <code>NETWORK_ERROR</code>, и последующий код не будет исполнен. Тем не менее код, исполненный ранее (включая отложенный при помощи {{domxref("window.setTimeout()")}}) останется функционален. Объявления функций идущие <strong>после</strong> вызова метода <code>importScripts()</code> также будут доступны, т.к. объявления функций всегда обрабатываются перед остальным кодом.</p> - -<div class="note"><strong>Заметка</strong>: Скрипты могут быть загружены в произвольном порядке, но их исполнение будет в том порядке, в котором имена файлов были переданы в <code>importScripts()</code>. Функция выполняется синхронно; <code>importScripts()</code> не вернет исполнение, пока все скрипты не будут загружены и исполнены.</div> - -<h2 id="Разделяемые_worker-ы_Shared_workers">Разделяемые worker-ы (Shared workers)</h2> - -<p>Разделяемый worker доступен нескольким разным скриптам — даже если они находятся в разных окнах, фреймах или даже worker-ах. В этом разделе мы обсудим JavaScript, который можно найти в нашем <a class="external external-icon" href="https://github.com/mdn/simple-shared-worker">базовом примере разделяемых worker-ов</a> (<a class="external external-icon" href="http://mdn.github.io/simple-shared-worker/">запустить разделяемый worker</a>): Он очень похож на базовый пример выделенных worker-ов, за исключением двух функций, которые доступны из разных скриптовых файлов: <em>умножение двух чисел</em> или <em>возведение числа в степень.</em> Оба скрипта используют один и тот же worker для необходимых вычислений.</p> - -<p>Здесь мы сосредоточимся на разнице между выделенными и раздялемыми worker-ами. Обратите внимание, что в данном примере есть две HTML страницы с JavaScript кодом, которые используют один и тот же файл worker-а.</p> - -<div class="note"> -<p><strong>Заметка</strong>: Если разделяемый worker может быть доступен из нескольких контекстов просмотра, то все они должны иметь одно и то же происхождение (одни и те же протокол, хост и порт).</p> -</div> - -<div class="note"> -<p><strong>Заметка: </strong>В Firefox разделяемый worker не может быть использован совместно документами в приватном и неприватном окне ({{bug(1177621)}}).</p> -</div> - -<h3 id="Создание_разделяемого_worker-а">Создание разделяемого worker-а</h3> - -<p>Запуск разделяемого worker-а очень похож на запуск выделенного worker-а, но используется другой конструктор (см. <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/index.html">index.html</a> и <a href="http://mdn.github.io/simple-shared-worker/index2.html">index2.html</a>) — в каждом документе необходимо поднять worker, для этого следует написать такой код:</p> - -<pre class="brush: js notranslate">var myWorker = new SharedWorker("worker.js");</pre> - -<p>Большая разница заключается в том, что с разделяемым worker-ом необходимо взаимодействовать через объект <code>port</code> — явно открыв порт, с помощью которого скрипты могут взаимодействовать с worker-ом (в случае выделенного worker-а это происходит неявно).</p> - -<p>Соединение с портом должно быть осуществлено либо неявно, используя обработчик событие <code>onmessage</code>, либо явно, вызвав метод <strong>start()</strong> перед тем, как отправлять любые сообщения. Вызов метода start() необходим только тогда, когда подписка на событие реализована через метод <code>addEventListener()</code>.</p> - -<div class="blockIndicator note"> -<p><strong>Заметка: </strong>Когда используется метод <code>start()</code> чтобы открыть соединение с портом, его необходимо вызывать и в родительском потоке и в потоке worker-а, если необходима двухсторонняя коммуникация.</p> -</div> - -<pre class="brush: js notranslate">myWorker.port.start(); // в родительском потоке</pre> - -<pre class="brush: js notranslate">port.start(); // в потоке worker-а, где переменная <code>port</code> является ссылкой на порт</pre> - -<h3 id="Передача_сообщений_виз_разделяемого_worker-а">Передача сообщений в/из разделяемого worker-а</h3> - -<p>Теперь сообщения могут быть отправлены worker-у, как и прежде, но метод <code>postMessage()</code> должен вызываться из объекта <code>port</code> (еще раз, вы можете увидеть схожие кострукции в <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/multiply.js">multiply.js</a> и <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/square.js">square.js</a>):</p> - -<pre class="brush: js notranslate">squareNumber.onchange = function() { - myWorker.port.postMessage([squareNumber.value,squareNumber.value]); - console.log('Message posted to worker'); -}</pre> - -<p>Теперь на стороне worker-а. Здесь код немного сложнее (<a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/worker.js">worker.js</a>):</p> - -<pre class="brush: js notranslate">self.addEventListener('connect', function(e) { // требуется addEventListener() - var port = e.ports[0]; - port.onmessage = function(e) { - var workerResult = 'Result: ' + (e.data[0] * e.data[1]); - port.postMessage(workerResult); - } - <s>port.start();</s> // вызов необязательный, т.к. используется обработчик событий onmessage -});</pre> - -<p>Первый этап состоит из события <code>onconnect</code>. Оно срабатывает, когда произошло подключение (т.е. когда в родительском потоке отработало событие <code>onmessage</code> или когда в нем был вызван метод <code>start()</code>).</p> - -<p>Мы используем атрибут события <code>ports</code>, чтобы получить порт и сохранить его в переменной.</p> - -<p>Второй этап — это обработчик события <code>message</code> на сохраненном порту. Он нужен для подсчета и вывода результата вычисления в основной поток. Установка обработчика <code>message</code> в потоке worker-а также открывает подключение к родительскому потоку, поэтому вызов на <code>port.start()</code> на самом деле не нужен (см. код обработчика <code>onconnect</code>).</p> - -<p>Последний этап — возвращение в основной поток и обработка сообщения от worker‑а (еще раз, вы можете увидеть схожие конструкции в <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/multiply.js">multiply.js</a> и <a href="https://github.com/mdn/simple-shared-worker/blob/gh-pages/square.js">square.js</a>):</p> - -<pre class="brush: js notranslate">myWorker.port.onmessage = function(e) { - result2.textContent = e.data[0]; - console.log('Message received from worker'); -}</pre> - -<p>Когда сообщение приходит через порт от worker-а, мы проверяем тип результата вычислений и затем вставляем его в соответствующий абзац.</p> - -<h2 id="О_потоковой_безопасности">О потоковой безопасности</h2> - -<p>Интерфейс {{domxref("Worker")}} создаёт настоящие потоки на уровне операционной системы, что может смутить опытных программистов и навести их на мысли о проблемах, связанных с конфликтом доступа к общим объектам.</p> - -<p>На самом деле создать такие проблемы достаточно сложно, так как worker-ы жёстко контролируются. У них нет доступа к непотокобезопасным объектам DOM, а все данные между потоками передаются в качестве сериализованных объектов. Придётся очень постараться, чтобы вызывать проблемы потокобезопасности в вашем коде.</p> - -<h2 id="Передача_данных_в_и_из_worker-ов_другие_детали">Передача данных в и из worker-ов: другие детали</h2> - -<p>Передача данных между главной страницей и worker-ом происходит путем копирования, а не передачи по ссылке. Объекты сериализуются при передаче и затем десериализуются на другом конце. Страница и worker не используют совместно одни и те же экземпляры, для каждого создается свой. Большинство браузеров реализуют это структурированным клонированием (<a href="/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm">structured cloning</a>).</p> - -<p>Для иллюстрации этого мы создадим функцию <code>emulateMessage()</code>, которая будет имитировать поведение значения, которое клонируется, но не используется совместно при переходе от worker-а к главной странице или наоборот.</p> - -<pre class="brush: js notranslate">function emulateMessage (vVal) { - return eval("(" + JSON.stringify(vVal) + ")"); -} - -// Tests - -// test #1 -var example1 = new Number(3); -console.log(typeof example1); // object -console.log(typeof emulateMessage(example1)); // number - -// test #2 -var example2 = true; -console.log(typeof example2); // boolean -console.log(typeof emulateMessage(example2)); // boolean - -// test #3 -var example3 = new String("Hello World"); -console.log(typeof example3); // object -console.log(typeof emulateMessage(example3)); // string - -// test #4 -var example4 = { - "name": "John Smith", - "age": 43 -}; -console.log(typeof example4); // object -console.log(typeof emulateMessage(example4)); // object - -// test #5 -function Animal (sType, nAge) { - this.type = sType; - this.age = nAge; -} -var example5 = new Animal("Cat", 3); -alert(example5.constructor); // Animal -alert(emulateMessage(example5).constructor); // Object</pre> - -<p>Значения, которые клонируются и совместно не используются, называются сообщениями. Как вы, возможно, знаете, сообщения могут быть отправлены в главную страницу и из нее, используя <code>postMessage()</code>, и {{domxref("MessageEvent.data", "data")}}, содержа данные, передаваемые из worker-а.</p> - -<p><strong>example.html</strong>: (главная страница):</p> - -<pre class="brush: js notranslate">var myWorker = new Worker("my_task.js"); - -myWorker.onmessage = function (oEvent) { - console.log("Worker said : " + oEvent.data); -}; - -myWorker.postMessage("ali");</pre> - -<p><strong>my_task.js</strong> (worker):</p> - -<pre class="brush: js notranslate">postMessage("I\'m working before postMessage(\'ali\')."); - -onmessage = function (oEvent) { - postMessage("Hi " + oEvent.data); -};</pre> - -<p>Алгоритм структурированного клонирования может принять JSON и некоторые вещи, которые JSON не может принять, например, циклические ссылки.</p> - -<h3 id="Примеры_передачи_данных">Примеры передачи данных</h3> - -<h4 id="Пример_1_Расширенная_передача_JSON_данных_и_создание_системы_коммутации">Пример #1: Расширенная передача JSON данных и создание системы коммутации</h4> - -<p>Если вам нужно передать сложные данные и вызвать множество различных функций как на главной странице, так и в worker-е, вы можете создать следующую систему.</p> - -<p>В первую очередь мы создаем класс QueryableWorker, который принимает url worker-а, стандартный обработчик событий (defaultListener) и обработчик ошибок. Этот класс будет отслеживать всех обработчиков и поможет нам общаться с воркером.</p> - -<pre class="brush: js notranslate"><code>function QueryableWorker(url, defaultListener, onError) { - var instance = this, - worker = new Worker(url), - listeners = {}; - - this.defaultListener = defaultListener || function() {}; - - if (onError) {worker.onerror = onError;} - - this.postMessage = function(message) { - worker.postMessage(message); - } - - this.terminate = function() { - worker.terminate(); - } -}</code> -</pre> - -<p>Затем мы добавляем методы добавления/удаления обработчиков.</p> - -<pre class="brush: js notranslate"><code>this.addListeners = function(name, listener) { - listeners[name] = listener; -} - -this.removeListeners = function(name) { - delete listeners[name]; -}</code> -</pre> - -<p>Здесь мы создадим у worker-а два простых события для примера: получение разницы двух чисел и создание оповещения через три секунды. Но сначала нам нужно реализовать метод sendQuery, который проверит есть ли вообще у worker-а обработчик, который мы собираемся вызвать.</p> - -<pre class="brush: js notranslate"><code>/* - Эта функция принимает по крайней мере один аргумент: имя метода, который мы хотим вызвать. - Далее мы можем передать методу необходимые ему аргументы. - */ -this.sendQuery = function() { - if (arguments.length < 1) { - throw new TypeError('QueryableWorker.sendQuery takes at least one argument'); - return; - } - worker.postMessage({ - 'queryMethod': arguments[0], - 'queryArguments': Array.prototype.slice.call(arguments, 1) - }); -}</code> -</pre> - -<p>Завершим QueryableWorker методом <code>onmessage</code>. Если worker имеет соответствующий метод, который мы запросили, он также должен вернуть соответствующий обработчик и аргументы, которые нам нужны. Останется лишь найти его в <code>listeners</code>:</p> - -<pre class="brush: js notranslate"><code>worker.onmessage = function(event) { - if (event.data instanceof Object && - event.data.hasOwnProperty('queryMethodListener') && - event.data.hasOwnProperty('queryMethodArguments')) { - listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments); - } else { - this.defaultListener.call(instance, event.data); - } -}</code> -</pre> - -<p>Теперь к самому worker-у. Сначала следует определить эти два простых метода:</p> - -<pre class="brush: js notranslate"><code>var queryableFunctions = { - getDifference: function(a, b) { - reply('printStuff', a - b); - }, - waitSomeTime: function() { - setTimeout(function() { - reply('doAlert', 3, 'seconds'); - }, 3000); - } -} - -function reply() { - if (arguments.length < 1) { - throw new TypeError('reply - takes at least one argument'); - return; - } - postMessage({ - queryMethodListener: arguments[0], - queryMethodArguments: Array.prototype.slice.call(arguments, 1) - }); -} - -/* This method is called when main page calls QueryWorker's postMessage method directly*/ -function defaultReply(message) { - // do something -}</code> -</pre> - -<p>И <code>onmessage</code>:</p> - -<pre class="brush: js notranslate"><code>onmessage = function(event) { - if (event.data instanceof Object && - event.data.hasOwnProperty('queryMethod') && - event.data.hasOwnProperty('queryMethodArguments')) { - queryableFunctions[event.data.queryMethod] - .apply(self, event.data.queryMethodArguments); - } else { - defaultReply(event.data); - } -}</code></pre> - -<p>Полный код примера:</p> - -<p><strong>example.html</strong> (основная страница):</p> - -<pre class="brush: html notranslate"><code><!doctype html> - <html> - <head> - <meta charset="UTF-8" /> - <title>MDN Example - Queryable worker</title> - <script type="text/javascript"> - /* - QueryableWorker instances methods: - * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function - * postMessage(string or JSON Data): see Worker.prototype.postMessage() - * terminate(): terminates the Worker - * addListener(name, function): adds a listener - * removeListener(name): removes a listener - QueryableWorker instances properties: - * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly - */ - function QueryableWorker(url, defaultListener, onError) { - var instance = this, - worker = new Worker(url), - listeners = {}; - - this.defaultListener = defaultListener || function() {}; - - if (onError) {worker.onerror = onError;} - - this.postMessage = function(message) { - worker.postMessage(message); - } - - this.terminate = function() { - worker.terminate(); - } - - this.addListener = function(name, listener) { - listeners[name] = listener; - } - - this.removeListener = function(name) { - delete listeners[name]; - } - - /* - This functions takes at least one argument, the method name we want to query. - Then we can pass in the arguments that the method needs. - */ - this.sendQuery = function() { - if (arguments.length < 1) { - throw new TypeError('QueryableWorker.sendQuery takes at least one argument'); - return; - } - worker.postMessage({ - 'queryMethod': arguments[0], - 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) - }); - } - - worker.onmessage = function(event) { - if (event.data instanceof Object && - event.data.hasOwnProperty('queryMethodListener') && - event.data.hasOwnProperty('queryMethodArguments')) { - listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments); - } else { - this.defaultListener.call(instance, event.data); - } - } - } - - // your custom "queryable" worker - var myTask = new QueryableWorker('my_task.js'); - - // your custom "listeners" - myTask.addListener('printStuff', function (result) { - document.getElementById('firstLink').parentNode.appendChild(document.createTextNode('The difference is ' + result + '!')); - }); - - myTask.addListener('doAlert', function (time, unit) { - alert('Worker waited for ' + time + ' ' + unit + ' :-)'); - }); -</script> -</head> -<body> - <ul> - <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li> - <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li> - <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li> - </ul> -</body> -</html></code></pre> - -<p><strong>my_task.js</strong> (код worker-а):</p> - -<pre class="brush: js notranslate"><code>var queryableFunctions = { - // пример #1: получить разницу между двумя числами - getDifference: function(nMinuend, nSubtrahend) { - reply('printStuff', nMinuend - nSubtrahend); - }, - // пример #2: подождать три секунды - waitSomeTime: function() { - setTimeout(function() { reply('doAlert', 3, 'seconds'); }, 3000); - } -}; - -// системные функции - -function defaultReply(message) { - // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly - // do something -} - -function reply() { - if (arguments.length < 1) { throw new TypeError('reply - not enough arguments'); return; } - postMessage({ 'queryMethodListener': arguments[0], 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) }); -} - -onmessage = function(oEvent) { - if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty('queryMethod') && oEvent.data.hasOwnProperty('queryMethodArguments')) { - queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments); - } else { - defaultReply(oEvent.data); - } -};</code> -</pre> - -<p>Можно переключать содержимое каждой главной страницы -> worker и worker -> сообщение главной страницы. И имена свойств "queryMethod", "queryMethodListeners", "queryMethodArguments" могут быть любыми пока они согласуются с <code>QueryableWorker</code> и <code>worker</code>.</p> - -<h3 id="Передача_данных_с_помощью_передачи_владения_передаваемые_объекты">Передача данных с помощью передачи владения (передаваемые объекты)</h3> - -<p>Google Chrome 17+ and Firefox 18+ имеют дополнительную возможность передачи определенных типов объектов (передаваемые объекты реализующие {{domxref("Transferable")}} интерфейс) к или из worker-а с высокой призводительностью. Эти объекты передаются из одного контекста в другой без операций копирования, что приводит к значительному повышению производительности при отправке больших наборов данных. Думайте об этом как о передаче по ссылке в мире C/C++. Однако в отличии от передачи по ссылке, "версия" из вызывающего контекста больше недоступна после передачи. Владельцем становится новый контекст. Для примера, после передачи {{domxref("ArrayBuffer")}} из главной страницы к worker-у, исходный {{domxref("ArrayBuffer")}} очищается и более недоступен для использования. Его содержание (в буквальном смысле) переносится в рабочий контекст.</p> - -<pre class="brush: js notranslate">// Create a 32MB "file" and fill it. -var uInt8Array = new Uint8Array(1024*1024*32); // 32MB -for (var i = 0; i < uInt8Array.length; ++i) { - uInt8Array[i] = i; -} - -worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]); -</pre> - -<div class="note"> -<p><strong>Заметка</strong>: Для дополнительной информации о передаваемых объектах, производительности и поддержки для этого метода, читайте <a href="http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast">Transferable Objects: Lightning Fast!</a> на HTML5 Rocks.</p> -</div> - -<h2 id="Встроенные_worker-ы">Встроенные worker-ы</h2> - -<p>Не существует утвержденного способа встроить код worker-а в рамках веб-страницы, как элемент {{HTMLElement("script")}} делает для обычных скриптов. Но элемент {{HTMLElement("script")}}, который не имеет аттрибута <code>src</code> и аттрибута <code>type</code>, которому не назначен выполняемый MIME type, можно считать блоком данных для использования JavaScript. Блок данных "Data blocks" — это более общее свойство HTML5, может содержать любые текстовые данные. Так, worker может быть встроен следующим образом:</p> - -<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="doctype token"><!DOCTYPE html></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>html</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>head</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>meta</span> <span class="attr-name token">charset</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>UTF-8<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>title</span><span class="punctuation token">></span></span>MDN Example - Embedded worker<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>title</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text/js-worker<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="script token"><span class="language-javascript token"> - <span class="comment token">// Этот script НЕ БУДЕТ анализироваться JS движками, потому что его MIME-тип text/js-worker.</span> - <span class="keyword token">var</span> myVar <span class="operator token">=</span> <span class="string token">'Hello World!'</span><span class="punctuation token">;</span> - <span class="comment token">// </span></span></span></code>Остальная часть кода вашего воркера идет сюда.<code class="language-html"><span class="script token"><span class="language-javascript token"> -</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text/javascript<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="script token"><span class="language-javascript token"> - <span class="comment token">// Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.</span> - <span class="keyword token">function</span> <span class="function token">pageLog</span><span class="punctuation token">(</span><span class="parameter token">sMsg</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> - <span class="comment token">// Use a fragment: browser will only render/reflow once.</span> - <span class="keyword token">var</span> oFragm <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">createDocumentFragment</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - oFragm<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">createTextNode</span><span class="punctuation token">(</span>sMsg<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - oFragm<span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">createElement</span><span class="punctuation token">(</span><span class="string token">'br'</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - document<span class="punctuation token">.</span><span class="function token">querySelector</span><span class="punctuation token">(</span><span class="string token">'#logDisplay'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">appendChild</span><span class="punctuation token">(</span>oFragm<span class="punctuation token">)</span><span class="punctuation token">;</span> - <span class="punctuation token">}</span> -</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text/js-worker<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="script token"><span class="language-javascript token"> - <span class="comment token">// Этот script НЕ БУДЕТ анализироваться JS движками, потому что его MIME-тип text/js-worker.</span> - <span class="function function-variable token">onmessage</span> <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">oEvent</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> - <span class="function token">postMessage</span><span class="punctuation token">(</span>myVar<span class="punctuation token">)</span><span class="punctuation token">;</span> - <span class="punctuation token">}</span><span class="punctuation token">;</span> - <span class="comment token">// </span></span></span></code>Остальная часть кода вашего воркера идет сюда.<code class="language-html"><span class="script token"><span class="language-javascript token"> -</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text/javascript<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="script token"><span class="language-javascript token"> - <span class="comment token">// Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.</span> - - <span class="comment token">// В прошлом...:</span> - <span class="comment token">// blob builder существовал</span> - <span class="comment token">// ... но теперь мы используем Blob...:</span> - <span class="keyword token">var</span> blob <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Blob</span><span class="punctuation token">(</span><span class="class-name token">Array</span><span class="punctuation token">.</span>prototype<span class="punctuation token">.</span><span class="function token">map</span><span class="punctuation token">.</span><span class="function token">call</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">querySelectorAll</span><span class="punctuation token">(</span><span class="string token">'script[type=\'text\/js-worker\']'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="keyword token">function</span> <span class="punctuation token">(</span><span class="parameter token">oScript</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="keyword token">return</span> oScript<span class="punctuation token">.</span>textContent<span class="punctuation token">;</span> <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">,</span><span class="punctuation token">{</span>type<span class="punctuation token">:</span> <span class="string token">'text/javascript'</span><span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - - <span class="comment token">// Создание нового свойства document.worker, содержащего все наши "text/js-worker" скрипты.</span> - document<span class="punctuation token">.</span>worker <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Worker</span><span class="punctuation token">(</span>window<span class="punctuation token">.</span><span class="constant token">URL</span><span class="punctuation token">.</span><span class="function token">createObjectURL</span><span class="punctuation token">(</span>blob<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - - document<span class="punctuation token">.</span>worker<span class="punctuation token">.</span><span class="function function-variable token">onmessage</span> <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">oEvent</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> - <span class="function token">pageLog</span><span class="punctuation token">(</span><span class="string token">'Received: '</span> <span class="operator token">+</span> oEvent<span class="punctuation token">.</span>data<span class="punctuation token">)</span><span class="punctuation token">;</span> - <span class="punctuation token">}</span><span class="punctuation token">;</span> - - <span class="comment token">// Запуск воркера.</span> - window<span class="punctuation token">.</span><span class="function function-variable token">onload</span> <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> document<span class="punctuation token">.</span>worker<span class="punctuation token">.</span><span class="function token">postMessage</span><span class="punctuation token">(</span><span class="string token">''</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="punctuation token">}</span><span class="punctuation token">;</span> -</span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>head</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>body</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>logDisplay<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>body</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>html</span><span class="punctuation token">></span></span></code> -</pre> - -<div id="logDisplay">Встраиваемый worker теперь внесен в новое custom свойство <code>document.worker</code></div> - -<div></div> - -<div>Также стоит отметить, что вы также можете преобразовать функцию в BLOB-объект, а затем сгенерировать URL объекта из этого BLOB-объекта. Например:</div> - -<pre class="notranslate">function fn2workerURL(fn) { - var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'}) - return URL.createObjectURL(blob) -} -</pre> - -<h2 id="Другие_примеры">Другие примеры</h2> - -<p>В этой секции представлено еще несколько примеров как использовать worker-ы.</p> - -<h3 id="Выполнение_вычислений_в_фоне">Выполнение вычислений в фоне</h3> - -<p>Worker-ы в основном полезны для того, чтобы позволить вашему коду выполнять ресурсоемкие вычисления, не блокируя поток пользовательского интерфейса. В этом примере, worker используется для вычисления числа Фибоначчи.</p> - -<h4 id="Код_JavaScript">Код JavaScript</h4> - -<p>Следующий код JavaScript хранится в файле "fibonacci.js", на который ссылается HTML в следующем разделе.</p> - -<pre class="brush: js notranslate">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); - } - };</pre> - -<p>Worker устанавливает свойство <code>onmessage</code> для функции, которая будет получать сообщения, отправленные при вызове <code>postMessage()</code> рабочего объекта (обратите внимание, что это отличается от определения глобальной <em>переменной</em> с таким именем или определения <em>функции</em> с таким именем. <code>var onmessage</code> и <code>function onmessage</code> будет определять глобальные свойства с этими именами , но они не будут регистрировать функцию для получения сообщений, отправленных веб-страницей, которая создала worker). Это запускает рекурсию, порождая новые копии для обработки каждой итерации вычисления.</p> - -<h4 id="HTML_код">HTML код</h4> - -<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="doctype token"><!DOCTYPE html></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>html</span><span class="punctuation token">></span></span> - <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>head</span><span class="punctuation token">></span></span> - <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>meta</span> <span class="attr-name token">charset</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>UTF-8<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> - <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>title</span><span class="punctuation token">></span></span>Test threads fibonacci<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>title</span><span class="punctuation token">></span></span> - <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>head</span><span class="punctuation token">></span></span> - <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>body</span><span class="punctuation token">></span></span> - - <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>result<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> - - <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>script</span> <span class="attr-name token">language</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>javascript<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="script token"><span class="language-javascript token"> - - <span class="keyword token">var</span> worker <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Worker</span><span class="punctuation token">(</span><span class="string token">'fibonacci.js'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - - worker<span class="punctuation token">.</span><span class="function function-variable token">onmessage</span> <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">event</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> - document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'result'</span><span class="punctuation token">)</span><span class="punctuation token">.</span>textContent <span class="operator token">=</span> event<span class="punctuation token">.</span>data<span class="punctuation token">;</span> - <span class="function token">dump</span><span class="punctuation token">(</span><span class="string token">'Got: '</span> <span class="operator token">+</span> event<span class="punctuation token">.</span>data <span class="operator token">+</span> <span class="string token">'\n'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - <span class="punctuation token">}</span><span class="punctuation token">;</span> - - worker<span class="punctuation token">.</span><span class="function function-variable token">onerror</span> <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="parameter token">error</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> - <span class="function token">dump</span><span class="punctuation token">(</span><span class="string token">'Worker error: '</span> <span class="operator token">+</span> error<span class="punctuation token">.</span>message <span class="operator token">+</span> <span class="string token">'\n'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - <span class="keyword token">throw</span> error<span class="punctuation token">;</span> - <span class="punctuation token">}</span><span class="punctuation token">;</span> - - worker<span class="punctuation token">.</span><span class="function token">postMessage</span><span class="punctuation token">(</span><span class="string token">'5'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> - - </span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>script</span><span class="punctuation token">></span></span> - <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>body</span><span class="punctuation token">></span></span> -<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>html</span><span class="punctuation token">></span></span></code></pre> - -<p>Веб-страница создает элемент <code>div</code> с ID <code>result</code> , который используется для отображения результата, а затем порождает worker. После порождения worker-а, обработчик <code>onmessage</code> настроен для отображения результатов путем установки содержимого элемента <code>div</code>, и обработчик <code>onerror</code> настроен на <a href="/en-US/docs/Debugging_JavaScript#dump.28.29">выброс</a> сообщения об ошибке.</p> - -<p>Наконец, сообщение отправляется worker-у, чтобы запустить его.</p> - -<p><a class="external" href="/samples/workers/fibonacci">Попробуйте этот пример</a>.</p> - -<h3 id="Выполнение_веб_IO_в_фоне">Выполнение веб I/O в фоне</h3> - -<p>Вы можете найти пример этого в статье <a class="internal" href="/en-US/docs/Using_workers_in_extensions">Использование worker-ов в расширениях</a>.</p> - -<h3 id="Разделение_задач_между_множественными_worker-ами">Разделение задач между множественными worker-ами</h3> - -<p>Поскольку многоядерные компьютеры становятся все более распространенными, часто бывает полезно разделить вычислительно сложные задачи между несколькими worker-ами, которые затем могут выполнить эти задачи на многопроцессорных ядрах.</p> - -<h2 id="Другие_типы_worker-ов">Другие типы worker-ов</h2> - -<p>В дополнение к выделенным и совместно используемым web worker-ам доступны другие типы worker-ов:</p> - -<ul> - <li><a href="/en-US/docs/Web/API/ServiceWorker_API">ServiceWorkers</a>, по сути, действуют как прокси-серверы, которые размещаются между веб-приложениями, браузером и сетью (при наличии). Они предназначены (помимо прочего) для создания эффективного автономного взаимодействия, перехвата сетевых запросов и принятия соответствующих действий в зависимости от того, доступна ли сеть, и обновлены ли ресурсы на сервере. Они также разрешают доступ push-уведомлениям и API фоновой синхронизации.</li> - <li>Chrome Workers это worker типа Firefox-only, который вы можете использовать, если вы разрабатываете дополнения и хотите использовать worker-ы в расширениях и иметь доступ к <a href="https://developer.mozilla.org/en/js-ctypes">js-ctypes</a> в вашем worker-е. Смотрите {{domxref("ChromeWorker")}} для более подробной информации.</li> - <li><a href="/en-US/docs/Web/API/Web_Audio_API#Audio_Workers">Audio Workers</a> предоставляют возможность прямой обработки звука по сценарию в контексте web worker-а.</li> -</ul> - -<h2 id="Функции_и_интерфейсы_доступные_в_worker-ах">Функции и интерфейсы доступные в worker-ах</h2> - -<p>Внутри web worker-а вы можете использовать большинство стандартных функций JavaScript, включая:</p> - -<ul> - <li>{{domxref("Navigator")}}</li> - <li>{{domxref("XMLHttpRequest")}}</li> - <li>{{jsxref("Global_Objects/Array", "Array")}}, {{jsxref("Global_Objects/Date", "Date")}}, {{jsxref("Global_Objects/Math", "Math")}}, и {{jsxref("Global_Objects/String", "String")}}</li> - <li>{{domxref("Window.requestAnimationFrame")}}, {{domxref("WindowTimers.setTimeout")}}, и {{domxref("WindowTimers.setInterval")}}</li> -</ul> - -<p>Главное, что вы не можете сделать в Worker это напрямую повлиять на родительскую страницу. Это включает в себя манипулирование DOM и использование объектов этой страницы. Вы должны сделать это косвенно, отправив сообщение обратно основному сценарию через {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, а затем выполнив изменения оттуда.</p> - -<div class="note"> -<p><strong>Заметка</strong>: Для знакомства с полным списком функций, доступных для worker-ов, смотрите статью <a href="/en-US/docs/Web/Reference/Functions_and_classes_available_to_workers">Функции и интерфейсы доступные worker-ам</a>.</p> -</div> - -<h2 id="Спецификации">Спецификации</h2> - -<table class="standard-table"> - <tbody> - <tr> - <th scope="col">Спецификация</th> - <th scope="col">Статус</th> - <th scope="col">Комментарий</th> - </tr> - <tr> - <td>{{SpecName('HTML WHATWG', '#toc-workers')}}</td> - <td>{{Spec2('HTML WHATWG')}}</td> - <td>Без изменений {{SpecName("Web Workers")}}.</td> - </tr> - <tr> - <td>{{SpecName('Web Workers')}}</td> - <td>{{Spec2('Web Workers')}}</td> - <td>Начальное определение.</td> - </tr> - </tbody> -</table> - -<h2 id="Браузерная_совместимость">Браузерная совместимость</h2> - -<div>{{CompatibilityTable}}</div> - -<div id="compat-desktop"> -<table class="compat-table"> - <tbody> - <tr> - <th>Feature</th> - <th>Chrome</th> - <th>Firefox (Gecko)</th> - <th>Internet Explorer</th> - <th>Opera</th> - <th>Safari (WebKit)</th> - </tr> - <tr> - <td>Basic support</td> - <td>4<sup>[1]</sup></td> - <td>{{CompatGeckoDesktop("1.9.1")}}</td> - <td>10.0</td> - <td>10.6<sup>[1]</sup></td> - <td>4<sup>[2]</sup></td> - </tr> - <tr> - <td>Shared workers</td> - <td>4<sup>[1]</sup></td> - <td>{{CompatGeckoDesktop(29)}}</td> - <td>{{CompatNo}}</td> - <td>10.6</td> - <td>5<br> - {{CompatNo}} 6.1<sup>[4]</sup></td> - </tr> - <tr> - <td>Passing data using <a href="/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm">structured cloning</a></td> - <td>13</td> - <td>{{CompatGeckoDesktop(8)}}</td> - <td>10.0</td> - <td>11.5</td> - <td>6</td> - </tr> - <tr> - <td>Passing data using <a class="external" href="http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objects">transferable objects</a></td> - <td>17 {{property_prefix("webkit")}}<br> - 21</td> - <td>{{CompatGeckoDesktop(18)}}</td> - <td>{{CompatNo}}</td> - <td>15</td> - <td>6</td> - </tr> - <tr> - <td>Global {{domxref("window.URL", "URL")}}</td> - <td>10<sup>[3]</sup><br> - 23</td> - <td>{{CompatGeckoDesktop(21)}}</td> - <td>11</td> - <td>15</td> - <td>6<sup>[3]</sup></td> - </tr> - </tbody> -</table> -</div> - -<div id="compat-mobile"> -<table class="compat-table"> - <tbody> - <tr> - <th>Feature</th> - <th>Android</th> - <th>Chrome for Android</th> - <th>Firefox Mobile (Gecko)</th> - <th>Firefox OS (Gecko)</th> - <th>IE Phone</th> - <th>Opera Mobile</th> - <th>Safari Mobile</th> - </tr> - <tr> - <td>Basic support</td> - <td>4.4</td> - <td>4<sup>[1]</sup></td> - <td>3.5</td> - <td>1.0.1</td> - <td>10.0</td> - <td>11.5<sup>[1]</sup></td> - <td>5.1<sup>[2]</sup></td> - </tr> - <tr> - <td>Shared workers</td> - <td>{{CompatNo}}</td> - <td>4<sup>[1]</sup></td> - <td>8</td> - <td>1.0.1</td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - </tr> - <tr> - <td>Passing data using <a href="/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm">structured cloning</a></td> - <td>{{CompatNo}}</td> - <td>4</td> - <td>8</td> - <td>1.0.1</td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - </tr> - <tr> - <td>Passing data using <a class="external" href="http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#transferable-objects">transferable objects</a></td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - <td>18</td> - <td>1.0.1</td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - <td>{{CompatNo}}</td> - </tr> - </tbody> -</table> -</div> - -<p>[1] Chrome и Opera выдают ошибку "<code>Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'.</code>" когда вы пытаетесь запустить worker локально. Нужно быть на надлежащем домене.</p> - -<p>[2] Начиная с Safari 7.1.2, вы можете вызывать <code>console.log</code> изнутри worker-а, но он ничего не выведет в консоль. Более старые версии Safari не ползволяют вызывать <code>console.log</code> изнутри worker-а</p> - -<p>[3] Эта функция реализована с префиксом как <code>webkitURL</code>.</p> - -<p>[4] Safari <a href="https://bugs.webkit.org/show_bug.cgi?id=116359">удалил поддержку SharedWorker</a>.</p> - -<h2 id="Смотрите_также">Смотрите также</h2> - -<ul> - <li><code><a class="internal" href="/en-US/docs/Web/API/Worker">Worker</a></code> интерфейс</li> - <li><code><a class="internal" href="/en-US/docs/Web/API/SharedWorker">SharedWorker</a></code> интерфейс</li> - <li><a href="/en-US/docs/Web/API/Worker/Functions_and_classes_available_to_workers">Функции доступные для worker-ов</a></li> - <li><a href="/en-US/docs/Web/API/Web_Workers_API/Using_web_workers">Продвинутые концепции и примеры</a></li> -</ul> |