- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Выразительный JavaScript - Марейн Хавербеке
Шрифт:
Интервал:
Закладка:
У картинки среднего размера много пикселей. Постарайтесь свести работу программы к минимуму, или же она будет работать слишком долго. К примеру, игнорируйте пиксели, которые вы уже обрабатывали.
Рекомендую для окраски отдельных пикселей вызывать fillRect, и хранить какую-то структуру данных, где записано, какие пиксели вы уже обошли.
<script>
tools["Flood fill"] = function(event, cx) {
// Ваш код
};
</script>
<link rel="stylesheet" href="css/paint.css">
<body>
<script>createPaint(document.body);</script>
</body>
20. Node.js
Ученик спросил: «Программисты встарь использовали только простые компьютеры и программировали без языков, но они делали прекрасные программы. Почему мы используем сложные компьютеры и языки программирования?». Фу-Тзу ответил: «Строители встарь использовали только палки и глину, но они делали прекрасные хижины».
Мастер Юан-Ма, «Книга программирования»На текущий момент вы учили язык JavaScript и использовали его в единственном окружении: в браузере. В этой и следующей главе мы кратко представим вам Node.js, программу, которая позволяет применять навыки JavaScript вне браузера. С ней вы можете написать всё, от утилит командной строки до динамических HTTP серверов.
Эти главы посвящены обучению важным идеям, составляющим Node.js и предназначены для передачи вам достаточного количества информации, чтобы вы могли писать полезные программы в этой среде. Они не пытаются быть всеобъемлющими справочниками по Node.
Код из предыдущих глав вы могли писать и исполнять прямо в браузере, но код из этой главы написан для Node и в браузере работать не будет.
Если вы хотите сразу запускать код из этой главы, начните с установки Node с сайта nodejs.org для вашей операционки. Также на этом сайте вы найдёте документацию по Node и его встроенным модулям.
Вступление
Одна из наиболее сложных проблем при написании систем, общающихся по сети – обработка ввода и вывода. Чтение и запись данных в сеть и из сети, на диск и на другие устройства. Перемещение данных требует времени, и грамотное планирование этих действий может сильно повлиять на время отклика системы для пользователя или сетевых запросов.
В традиционном методе обработки ввода и вывода принято, что функция, к примеру, readFile, начинает читать файл и возвращается только когда файл полностью прочитан. Это называется синхронным вводом-выводом (synchronous I/O, input/output).
Node был задуман с целью облегчить и упростить использование асинхронного I/O. Мы уже встречались с асинхронными интерфейсами, такими, как объект браузера XMLHttpRequest, обсуждавшийся в главе 17. Такой интерфейс позволяет скрипту продолжать работу, пока интерфейс делает свою, и вызывает функцию обратного вызова по окончанию работы. Таким образом в Node работает весь I/O.
JavaScript легко вписывается в систему типа Node. Это один из немногих языков, в которые не встроена система I/O. Поэтому JavaScript легко встраивается в довольно эксцентричный подход к I/O в Node и в результате не порождает две разных системы ввода и вывода. В 2009 году при разработке Node люди уже использовали в браузере I/O, основанный на обратных вызовах, поэтому сообщество вокруг языка было привычно к асинхронному стилю программирования.
Асинхронность
Попробую проиллюстрировать разницу в синхронном и асинхронном подходах в I/O на небольшом примере, где программа должна получить два ресурса из интернета, и затем сделать что-то с данными.
В синхронном окружении очевидным способом решения задачи будет сделать запросы последовательно. У этого метода есть минус – второй запрос начнётся только после окончания первого. Общее время будет не меньше, чем сумма времени на обработку двух запросов. Это неэффективное использование компьютера, который большую часть времени будет простаивать, пока происходит передача данных по сети.
Решение проблемы в синхронной системе – запуск дополнительных потоков контроля исполнения программы (в главе 14 мы их уже обсуждали). Второй поток может запустить второй запрос, и затем оба потока будут ждать возврата результата, после чего они заново будут синхронизированы для сведения работы в один результат.
На диаграмме жирные линии обозначают время нормальной работы программы, а тонкие – время ожидания I/O. В синхронной модели время, затраченное на I/O, входит во временной график каждого из потоков. В асинхронной, запуск действия по I/O приводит к разветвлению временной линии. Поток, запустивший I/O, продолжает выполнение, а I/O выполняется параллельно ему, по окончанию работы делая обратный вызов функции.
Поток выполнения программы для синхронного и асинхронного I/O.
Ещё один способ выразить эту разницу: в синхронной модели ожидание окончания I/O неявное, а в асинхронной – явное, и находится под нашим непосредственным контролем. Но асинхронность работает в обе стороны. С её помощью выражать программы, не работающие по принципу прямой линии, проще, но выражать прямолинейные программы становится сложнее.
В главе 17 я уже касался того факта, что обратные вызовы привносят кучу шума и делают программу менее упорядоченной. Является ли такой подход в общем хорошей идеей – спорный вопрос. В любом случае, требуется время, чтобы привыкнуть к нему.
Но для системы, основанной на JavaScript, я бы сказал, что использование асинхронности с обратными вызовами имеет смысл. Одна из сильных сторон JavaScript – простота, и попытки добавить в программу несколько потоков привели бы к сильному усложнению. Хотя обратные вызовы не делают код простым, их идея очень проста и в то же время достаточно сильна для того, чтобы писать высокопроизводительные веб-серверы.
Команда node
Когда в вашей системе установлен Node.js, у вас появляется программа под названием node, которая запускает файлы JavaScript. Допустим, у вас есть файл hello.js со следующим кодом:
var message = "Hello world";
console.log(message);
Вы можете выполнить свою программу из командной строки:
$ node hello.js
Hello world
Метод console.log в Node действует так же, как в браузере. Выводит кусок текста. Но в Node текст выводится на стандартный вывод, а не в консоль JavaScript в браузере.
Если запустить node без файла, он выдаст вам строку запроса, в которой можно писать код на JavaScript и получать результат.
$ node
> 1 + 1
2
> [-1, -2, -3].map(Math.abs)
[1, 2, 3]
> process.exit(0)
$
Переменная process, так же как и console, доступна в Node глобально. Она обеспечивает несколько способов для инспектирования и манипулирования программой. Метод exit заканчивает процесс, и ему можно передать код статуса окончания программы, который сообщает программе, запустившей node (в данном случае, программной оболочке), завершилась ли программа удачно (нулевой код) или с ошибкой (любое другое число).
Для доступа к аргументам командной строки, переданным программе, можно читать массив строк process.argv. В него также включены имя команды node и имя вашего скрипта, поэтому список аргументов начинается с индекса 2. Если файл showargv.js содержит только инструкцию console.log(process.argv), его можно запустить так:
$ node showargv.js one --and two
["node", "/home/marijn/showargv.js", "one", "--and", "two"]
Все стандартные глобальные переменные JavaScript — Array, Math, JSON, также есть в окружении Node. Но там отсутствует функционал, связанный с работой браузера, например document или alert.
Объект глобальной области видимости, который в браузере называется window, в Node имеет более осмысленное название global.
Модули
Кроме нескольких упомянутых переменных, вроде console и process, Node держит мало функционала в глобальной области видимости. Для доступа к остальным встроенным возможностям вам надо обращаться к системе модулей.
Система CommonJS, основанная на функции require, была описана в главе 10. Такая система встроена в Node и используется для загрузки всего, от встроенных модулей и скачанных библиотек до файлов, являющихся частями вашей программы.
При вызове require Node нужно преобразовать заданную строку в имя файла. Пути, начинающиеся с "/", "./" или "../", преобразуются относительно пути к текущему модулю, где "./" означает текущую директорию, "../" – директорию выше, а "/" – корневую директорию файловой системы. Если вы запросите "./world/world" из файла /home/marijn/elife/run.js, Node попробует загрузить файл /home/marijn/elife/world/world.js. Расширение .js можно опускать.