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

22.4.2. Область видимости фонового потока

22.4.2. Область видимости фонового потока

При создании нового фонового потока с помощью конструктора Worker() вы задаете URL-адрес файла с программным кодом на языке JavaScript. Этот программный код выполняется в новой, нетронутой среде выполнения JavaScript, полностью изолированной от сценария, запустившего фоновый поток. Глобальным объектом этой изолированной среды выполнения является объект WorkerGlobalScope. Объект WorkerGlobalScope - это чуть больше, чем просто глобальный объект JavaScript, но меньше, чем полноценный клиентский объект Window.

Объект WorkerGlobalScope имеет метод postMessage() и свойство обработчика события onmessage, подобные своим аналогам в объекте Worker, но действующие в обратном направлении. Вызов метода postMessage() внутри фонового потока сгенерирует событие «message» за его пределами, а сообщения, отправляемые извне, будут превращаться в события и передаваться обработчику onmessage. Обратите внимание: благодаря тому, что объект WorkerGlobalScope является глобальным объектом для фонового потока, метод postMessage() и свойство onmessage воспринимаются программным кодом, выполняющимся в фоновом потоке, как глобальная функция и глобальная переменная.

Функция close() позволяет фоновому потоку завершить свою работу, и по своему действию она напоминает метод terminate() объекта Worker. Отметьте, однако, что в объекте Worker нет метода, который позволил бы определить, прекратил ли работу фоновый поток, как и нет свойства обработчика события onclose. Если попытаться с помощью метода postMessage() передать сообщение фоновому потоку, который прекратил работу, это сообщение будет просто проигнорировано без возбуждения исключения. В общем случае, если фоновый поток может завершить работу самостоятельно вызовом метода close(), неплохо было бы предусмотреть отправку сообщения, извещающего о прекращении работы.

Наибольший интерес представляет глобальная функция importScripts(), определяемая объектом WorkerGlobalScope: фоновые потоки выполнения могут использовать ее для загрузки любых необходимых им библиотек. Например:

// Перед началом работы загрузить необходимые классы и утилиты
importScripts("collections/Set.js", "collections/Map.js", "utils/base64.js");

Функция importScripts() принимает один или более аргументов с URL-адресами, каждый из которых должен ссылаться на файл с программным кодом на языке JavaScript. Относительные URL-адреса интерпретируются относительно URL-адреса, переданного конструктору Worker(). Она загружает и выполняет указанные файлы один за другим в том порядке, в каком они были указаны. Если при загрузке или при выполнении сценария возникнет какая-либо ошибка, ни один из последующих сценариев не будет загружаться или выполняться. Сценарий, загруженный функцией importScripts(), сам может вызвать функцию importScripts(), чтобы загрузить необходимые ему файлы. Отметьте, однако, что функция importScripts() не запоминает, какие сценарии были загружены и не предусматривает защиту от циклических ссылок.

Функция importScripts() выполняется синхронно: она не вернет управление, пока не будут загружены и выполнены все сценарии. Сценарии, указанные в вызове функции importScripts(), можно использовать сразу, как только она вернет управление: нет никакой необходимости определять функцию обратного вызова или обработчик события. После того как вы свыклись с асинхронной природой клиентского JavaScript, такой возврат к простой, синхронной модели может показаться странным. Но в этом и заключается достоинство потоков выполнения: в фоновом потоке можно использовать блокирующие функции, не блокируя цикл событий в основном потоке выполнения и не блокируя вычисления, выполняемые параллельно в других фоновых потоках.

Поскольку для фоновых потоков выполнения WorkerGlobalScope является глобальным объектом, он обладает всеми свойствами базового глобального объекта JavaScript, такими как объект JSON, функция isNaN() и конструктор Date(). (Полный список можно найти в справочной статье Global, в третьей части книги.) Однако, кроме того, объект WorkerGlobalScope имеет следующие свойства клиентского объекта Window:

self - ссылка на сам глобальный объект. Отметьте, однако, что в объекте WorkerGlobalScope отсутствует синонимичное свойство window, имеющееся в объекте Window.

Модель выполнения фонового потока

Фоновые потоки выполняют свой программный код (и все импортированные сценарии) синхронно, от начала до конца, и затем переходят в асинхронную фазу выполнения, когда они откликаются на события и таймеры. Если фоновый поток регистрирует обработчик события onmessage, он никогда не завершит работу, пока есть вероятность поступления событий «message». Но если фоновый поток не принимает сообщения, он будет работать, пока не будут выполнены все задания (такие как загрузка или таймеры) и не будут вызваны все функции, связанные с этими заданиями. После вызова всех зарегистрированных функций обратного вызова в фоновом потоке нет никакой возможности начать выполнять новые задания, поэтому он может смело завершить свою работу. Представьте себе фоновый поток без обработчика событий onmessage, который загружает файл с помощью объекта XMLHttpRequest. Если обработчик onload запустит загрузку другого файла или зарегистрирует обработчик таймера вызовом функции setTimeout(), поток выполнения получит новое задание и продолжит работу. Иначе он завершится.

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

• Методы работы с таймерами setTimeout(), clearTimeout(), setInterval() и clearInterval().

• Свойство location, содержащее URL-адрес, переданный конструктору Worker( Это свойство ссылается на объект Location, как и аналогичное ему свойство location объекта Window. Объект Location имеет свойства href, protocol, host, hostname, port, pathname, search и hash. В фоновом потоке эти свойства доступны только для чтения.

• Свойство navigator, ссылающееся на объект, обладающий теми же свойствами, что и объект Navigator окна. Объект navigator фонового потока имеет свойства appName, appVersion, platform, userAgent и onLine.

• Обычные методы объектов, в которых могут возбуждаться события: addEventListener() и removeEventListener().

• Свойство onerror, которому можно присвоить функцию обработки ошибок, подобное свойству Window.onerror, которое описывается в разделе 14.6. Обработчик ошибок, если его зарегистрировать, будет получать три аргумента с сообщением об ошибке, URL-адресом и номером строки. Он может вернуть false, чтобы показать, что ошибка обработана и не должна распространяться дальше в виде события «error» в объекте Worker. (Однако на момент написания этих строк обработка ошибок в разных броузерах была реализована несовместимым способом.)

Дополнительные особенности объекта Worker

Фоновые потоки выполнения, описываемые в этом разделе, являются выделенными фоновыми потоками: они связаны (или выделены из) с общим родительским потоком выполнения. Спецификация «Web Workers» определяет еще один тип фоновых потоков выполнения, разделяемые потоки выполнения. На момент написания этих строк броузеры еще не поддерживали разделяемые потоки выполнения. Однако их назначение состоит в том, чтобы играть роль именованного ресурса, который может предоставлять вычислительные услуги любым другим потокам выполнения. На практике взаимодействие с разделяемым потоком выполнения напоминает взаимодействие с сервером посредством сетевых сокетов.

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

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

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

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

Оглавление книги


Генерация: 1.190. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз