Книга: Выразительный JavaScript
Потоки
Потоки
Мы видели два примера потоков в примерах HTTP – объект response
, в который сервер может вести запись, и объект request
, который возвращается из http.request
.
Потоки с возможностью записи – популярная концепция в интерфейсах Node. У всех потоков есть метод write
, которому можно передать строку или объект Buffer
. Метод end
закрывает поток, а при наличии аргумента, выведет перед закрытием кусочек данных. Обоим методам можно задать функцию обратного вызова через дополнительный аргумент, которую они вызовут по окончанию записи или закрытию потока.
Возможно создать поток, показывающий на файл, при помощи функции fs.createWriteStream
. Затем можно использовать метод write
для записи в файл по кусочкам, а не целиком, как в fs.writeFile
.
Потоки с возможностью чтения будут чуть сложнее. Как переменная request
, переданная функции для обратного вызова в сервере HTTP, так и переменная response
, переданная в HTTP-клиенте, являются потоками с возможностью чтения. (Сервер читает запрос и потом пишет ответы, а клиент пишет запрос и читает ответа). Чтение из потока осуществляется через обработчики событий, а не через методы.
У объектов, создающих события в Node, есть метод on
, схожий с методом браузера addEventListener
. Вы даёте ему имя события и функцию, и он регистрирует эту функцию, чтоб её вызвали сразу, когда произойдёт событие.
У потоков с возможностью чтения есть события "data"
и "end"
. Первое происходит при поступлении данных, второе – по окончанию. Эта модель подходит к потоковым данным, которые можно сразу обработать, даже если получен не весь документ. Файл можно прочесть в виде потока через fs.createReadStream
.
Следующий код создаёт сервер, читающий тела запросов и отправляющий их в ответ потоком в виде текста из заглавных букв.
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
request.on("data", function(chunk) {
response.write(chunk.toString().toUpperCase());
});
request.on("end", function() {
response.end();
});
}).listen(8000);
Переменная chunk
, передаваемая обработчику данных, будет бинарным Buffer
, который можно преобразовать в строку, вызвав его метод toString
, который декодирует его с помощью кодировки по умолчанию (UTF-8).
Следующий код, будучи запущенным одновременно с сервером, отправит запрос на сервер и выведет полученный ответ:
var http = require("http");
var request = http.request({
hostname: "localhost",
port: 8000,
method: "POST"
}, function(response) {
response.on("data", function(chunk) {
process.stdout.write(chunk.toString());
});
});
request.end("Hello server");
Пример пишет в process.stdout
(стандартный вывод процесса, являющийся потоком с возможностью записи), а не в console.log
. Мы не можем использовать console.log
, так как он добавляет лишний перевод строки после каждого куска кода – это здесь не нужно.
- Стандартные потоки: stdin, stdout, stdeir, stdaux, stdprn.
- 1.2 Процесс, контекст процесса и потоки
- Потоки в пространстве ядра
- Структура mm_struct и потоки пространства ядра
- ГЛABA 6 Процессы, потоки и задания
- ГЛАВА 7 Потоки и планирование выполнения
- Процессы и потоки Windows
- Удаленные потоки
- Потоки и производительность
- Облегченные потоки
- Гиперпотоки и счетчик процессоров
- 12. Лекция: Потоки выполнения. Синхронизация