JavaScript. Подробное руководство, 6-е издание, стр. 384

Роль «сокета» для разделяемого потока выполнения играет объект Messa-gePort. Он определяет прикладной интерфейс обмена сообщениями, подобный аналогичному интерфейсу в выделенных потоках выполнения, а также используемому для обмена сообщениями между документами с разным происхождением. Объект MessagePort имеет метод postMessage() и атрибут onmessage обработчика событий. Спецификация HTML5 предусматривает возможность создания связанных пар объектов MessagePort с помощью конструктора MessageChannel(). Вы можете передавать объекты MessagePort (в специальном аргументе метода postMessage()) другим окнам или другим фоновым потокам выполнения и использовать их как выделенные каналы связи. Объекты MessagePort и MessageChannel являются дополнительным прикладным интерфейсом, который поддерживается лишь немногими броузерами и здесь не рассматривается.

**************************************************

Наконец, объект

<b>WorkerGlobalScope</b>
включает конструкторы объектов, важных для клиентских сценариев. В их числе конструктор
<b>XMLHttpRequest(),</b>
позволяющий фоновым потокам выполнять HTTP-запросы (глава 18), и конструктор
<b>Worker()</b>
, дающий возможность фоновым потокам создавать свои фоновые потоки. (Однако на момент написания этих строк конструктор
<b>Worker()</b>
был недоступен фоновым потокам в броузерах Chrome и Safari.)

Некоторые прикладные интерфейсы HTML5, описываемые далее в этой главе, определяют особенности, доступные как через обычный объект

<b>Window</b>
, так и через объект
<b>WorkerGlobalScope</b>
. Часто асинхронному прикладному интерфейсу объекта
<b>Window</b>
соответствует его синхронная версия в объекте
<b>WorkerGlobalScope</b>
. Эти прикладные интерфейсы «с поддержкой фоновых потоков выполнения» мы рассмотрим далее в этой главе.

22.4.3. Примеры использования фоновых потоков

Завершают этот раздел два примера использования фоновых потоков выполнения. Первый демонстрирует, как реализовать выполнение длительных вычислений в фоновом потоке, чтобы они не влияли на отзывчивость пользовательского интерфейса, обслуживаемого основным потоком выполнения. Второй демонстрирует, как можно использовать фоновые потоки для работы с простейшими синхронными прикладными интерфейсами.

В примере 22.6 определяется функция

<b>smear(),</b>
которая принимает элемент
<b>&lt;img&gt;</b>
в виде аргумента. Она применяет эффект размытия для «смазывания» изображения вправо. Для реализации этого эффекта используется описанный в главе 21 прием копирования изображения в неотображаемый элемент
<b>&lt;canvas&gt;</b>
и последующего извлечения пикселей изображения с помощью объекта
<b>ImageData</b>
. Элементы
<b>&lt;img&gt;</b>
и
<b>&lt;canvas&gt;</b>
нельзя передать фоновому потоку выполнения с помощью метода
<b>postMessage()</b>
, но можно передать объект
<b>ImageData</b>
(подробности во врезке «Структурированные копии» выше). Пример 22.6 создает объект
<b>Worker</b>
и вызывает его метод
<b>postMessage</b>
(), чтобы передать ему изображение. Когда фоновый поток отправит обработанные пикселы изображения обратно, программный код скопирует их снова в элемент
<b>&lt;canvas&gt;,</b>
извлекая их как ресурс с URL-адресом вида data:// и устанавливая этот URL-адрес в качестве значения свойства
<b>src</b>
оригинального элемента
<b>&lt;img&gt;</b>
.

Пример 22.6. Создание фонового потока выполнения для обработки изображения

<b>// Асинхронная замена изображения его смазанной версией.</b>

<b>// Используется так: &lt;img src=&quot;testimage.jpg&quot; onclick=&quot;smear(this)&quot;/&gt; </b>

<b>function smear(img) {</b>

<b>  // Создать неотображаемый элемент &lt;canvas&gt; того же размера, что и изображение</b>

<b>  var canvas = document.createElement(&quot;canvas&quot;);</b>

<b>  canvas.width = img.width;</b>

<b>  canvas.height = img.height;</b>

<b>  // Скопировать изображение в холст и извлечь его пикселы</b>

<b>  var context = canvas.getContext(&quot;2d&quot;);</b>

<b>  context.drawImage(img, 0, 0);</b>

<b>  var pixels = context.getImageData(0,0,img.width,img.height)</b>

<b>  // Отправить пикселы фоновому потоку выполнения</b>

<b>  var worker = new Worker(&quot;SmearWorker.js&quot;); // Создать фоновый поток</b>

<b>  worker.postMessage(pixels); // Скопировать и отдать пикселы</b>

<b>  // Зарегистрировать обработчик для получения ответа от фонового потока</b>

<b>  worker.onmessage = function(e) {</b>

<b>    var smeared_pixels = e.data;                // Пикселы, полученные от потока</b>

<b>    context.putImageData(smeared_pixels, 0, 0); // Скопировать в холст</b>

<b>    img.src = canvas.toDataURL();               // А затем в изображение</b>

<b>    worker.terminate();                         // Остановить поток</b>

<b>    canvas.width = canvas.height = 0;           // Освободить память</b>

<b>  }</b>

<b>}</b>

В примере 22.7 приводится программный код реализации фонового потока, используемого в примере 22.6. Основу этого примера составляет функция обработки изображения: модифицированная версия примера 21.10. Обратите внимание, что этот пример настраивает свою инфраструктуру обмена сообщениями единственной строчкой программного кода: обработчик события onmessage просто накладывает эффект смазывания на изображение и сразу же отправляет его обратно.