Книга: JavaScript. Подробное руководство, 6-е издание
13.3.1. Синхронные, асинхронные и отложенные сценарии
13.3.1. Синхронные, асинхронные и отложенные сценарии
Когда поддержка JavaScript впервые появилась в веб-броузерах, не существовало никаких инструментов обхода и управления структурой содержимого документа. Единственный способ, каким JavaScript-код мог влиять на содержимое документа, - это генерировать содержимое в процессе загрузки документа. Делалось это с помощью метода document.write().
В примере 13.3 показано, как выглядел ультрасовременный JavaScript-код в 1996 году.
Пример 13.3. Генерация содержимого документа во время загрузки
<h1>Таблица факториалов</h1>
<script>
function factorial(n) { // Функция вычисления факториалов
if (п <= 1) return п;
else return n*factorial(n-1);
}
document.write("<table>"); // Начало HTML-таблицы
document.write("<tr><th>n</thxth>n!</th></tr>"); // Вывести заголовок таблицы
for(var і = 1; і <= 10; і++) { // Вывести 10 строк
document. write("<trxtd>" + і + "</tdxtd>" + factorial(i) + "</td></tr>");
}
document.write("</table>”); // Конец таблицы
document.write("Generated at " + new Date()); // Вывести время
</script>
Когда сценарий передает текст методу document.write(),
этот текст добавляется во входной поток документа, и механизм синтаксического анализа разметки HTML действует так, как если бы элемент <script>
был замещен этим текстом. Использование метода document.write()
более не считается хорошим стилем программирования, но его применение по-прежнему возможно (раздел 15.10.2), и этот факт имеет важное следствие. Когда механизм синтаксического анализа разметки HTML встречает элемент <script>,
он должен, по умолчанию, выполнить сценарий, прежде чем продолжить разбор и отображение документа. Это не является проблемой для встроенных сценариев, но если сценарий находится во внешнем файле, на который ссылается атрибут src
, это означает, что часть документа, следующая за сценарием, не появится в окне броузера, пока сценарий не будет загружен и выполнен.
Такой синхронный, или блокирующий, порядок выполнения действует только по умолчанию. Тег <script>
может иметь атрибуты defer
и async
, которые (в броузерах, поддерживающих их) определяют иной порядок выполнения сценариев. Это логические атрибуты - они не имеют значения; они просто должны присутствовать в теге <script>.
Согласно спецификации HTML5, эти атрибуты принимаются во внимание, только когда используются вместе с атрибутомsrc
, однако некоторые броузеры могут поддерживать атрибут defer
и для встроенных сценариев:
<script defer src="deferred.js"></script>
<script async src="async.js"></script>
Оба атрибута, defer
и async
, сообщают броузеру, что данный сценарий не использует метод document.write()
и не генерирует содержимое документа, и что броузер может продолжать разбор и отображение документа, пока сценарий загружается. Атрибут defer
заставляет броузер отложить выполнение сценария до момента, когда документ будет загружен, проанализирован и станет готов к выполнению операций. Атрибут async
заставляет броузер выполнить сценарий, как только это станет возможно, но не блокирует разбор документа на время загрузки сценария. Если тег <script>
имеет оба атрибута, броузер, поддерживающий оба этих атрибута, отдаст предпочтение атрибуту async
и проигнорирует атрибут defer
.
Обратите внимание, что отложенные сценарии выполняются в порядке их следования в документе. Асинхронные сценарии выполняются сразу же, как только будут загружены, т. е. они могут выполняться в произвольном порядке.
На момент написания этих строк атрибуты async
и defer
поддерживались не всеми броузерами, поэтому их следует рассматривать лишь как подсказки для оптимизации: веб-страницы должны проектироваться так, чтобы они продолжали корректно работать, даже если отложенные и асинхронные сценарии выполняются броузером синхронно.
Имеется возможность загружать и выполнять сценарии асинхронно, даже если броузер не поддерживает атрибут async
, для чего достаточно динамически создать элемент <script>
и вставить его в документ. Это действие реализует функция loadasync()
, представленная в примере 13.4. Используемые ею приемы описываются в главе 15.
Пример 13.4. Асинхронная загрузка и выполнение сценария
// Асинхронная загрузка сценария из указанного URL-адреса и его выполнение
function loadasync(url) {
var head = document.getElementsByTagName("head")[0]; // Отыскать <head>
var s = document.createElement("script"); // Создать элемент <script>
s.src = url; // Установить атрибут src
head.appendChild(s); // Вставить <script> в <head>
}
Примечательно, что данная функция loadasync()
загружает сценарии динамически - сценарии, не включенные в веб-страницу, и на которые отсутствуют статические ссылки из веб-страницы, загружаются в документ и становятся частью выполняемой JavaScript-программы.
- Как работают сценарии. События
- Скрипты продаж. Готовые сценарии «холодных» звонков и личных встреч
- У14.6 Отложенные классы и прототип
- Ошибка пятая: не держитесь за каждую строчку в своем сценарии
- Убедительные сценарии
- Сценарии Samba
- Сценарии preexec и postexec
- Статические данные, формы и CGI-сценарии
- Отложенные вызовы
- Глава 7 Обработка нижних половин и отложенные действия
- Сценарии, выполняемые при загрузке операционной системы
- Сценарии, выполняемые при завершении работы операционной системы