Monday, April 29, 2013

Основной цикл в Javascript

Inline image 2

Все мы слышали про ajax и node.js. Они прочно обосновались уже не просто в словарном запасе, но и в наборе инструментов веб-разработчика. Ajax — асинхронное подтягивание данных с сервера на страницу, node — фреймворк с асинхронным IO. Но как в таком однопоточном языке, как Javascript, реализуется та самая асинхронность?

Вы, наверное, уже догадались из заголовка, речь пойдет об основном цикле («main loop»).

Как в спецификации

Наченем издалека. Говорим «Javascript», подразумеваем «ECMAScript», говорим «ES», подразумеваем «JS» (если, конечно, Вы не работаете в Mozilla и Вас не зовут Брендан Айх). Логично будет начать со спецификации ECMAScript.

Открываем ECMA-262 и видим… что в ней вообще ничего не сказано про то, что скрипт должен делать после того, как отработает, как его поставить на паузу или остановить. Значит, это отдается на откуп окружению, в котором он выполняется.

Как это сделано в WSH

Самое, пожалуй, простое окружение — это Windows Script Host, он же WSH. Нагрузил процессор на 100%, отработал до конца, умер — вот такой нехитрый жизненный цикл. Из функций управления выполнением только старый добрый sleep(), который останавливает интерпретатор на n миллисекунд.

WScript.echo(new Date() + ': Hello world!');
WScript.sleep(1000);
WScript.echo(new Date() + ': Goodbye, cruel world!');

Для несложных задач этого вполне хватает, задачи же посложнее могут превратиться в бег с препятствиями.

Пример с потолка: в библиотеке стоит терминал на Windows 98, без клавиатуры, но зато с Internet Explorer 6, который в фуллскрине показывает каталог книг. Юные хулиганы повадились IE6 закрывать, а запустить его обратно библиотекарям нелегко. Как быть?

Создаем функцию для запуска IE, создаем в глобальном скопе коллбек с хитрым именем и запускаем.

function startIE () {
    var ie = WScript.CreateObject("InternetExplorer.Application", "ieEvent_");
    ie.Navigate("http://127.0.0.1/");
    ie.Visible = true;
    ie.FullScreen = true;
}

var ieEvent_OnQuit = startIE;

startIE();

Read more: Habrahabr.ru
QR: Inline image 1