Чтение онлайн

ЖАНРЫ

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

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

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

Некоторые прикладные интерфейсы HTML5, описываемые далее

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

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

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

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

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

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

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

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

function smear(img) {

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

var canvas = document.createElement("canvas");

canvas.width = img.width;

canvas.height = img.height;

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

var context = canvas.getContext("2d");

context.drawImage(img, 0, 0);

var pixels = context.getImageData(0,0,img.width,img.height)

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

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

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

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

worker.onmessage = function(e) {

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

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

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

worker.terminate; // Остановить поток

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

}

}

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

Пример 22.7. Обработка изображения в фоновом потоке выполнения

// Получает объект ImageData от основного потока выполнения, обрабатывает его

// и отправляет обратно

onmessage = function(e) { postMessage(smear(e.data)); }

// Смазывает пикселы в ImageData вправо, воспроизводя эффект быстрого движения.

// При обработке больших изображений этой функции приходится выполнять огромный объем

// вычислений, что может вызвать эффект подвисания пользовательского интерфейса,

// если использовать ее в основном потоке выполнения.

function smear(pixels) {

var data = pixels.data,

width = pixels.width,

height = pixels.height;

var n = 10, m = n-1; // Нем больше n, тем сильнее эффект смазывания

for(var row = 0; row < height; row++) { // Для каждой строки

var і = row*width*4 +4; // Индекс 2-го пиксела

for(var col = 1; col < width; col++, і += 4) { // Для каждого столбца

data[i] = (data[i] + data[i-4]*m)/n; // Красная составляющая

Поделиться с друзьями: