Платформа Node подходит для программирования потоков данных и организации
их передачи. Потоки данных можно представлять как массивы, но вместо
распределения данных в области (в массиве) выполняется распределение данных во
времени. Благодаря передаче данных фрагмент за фрагментом разработчик
получает возможность обрабатывать данные по мере их накопления, а не ждать,
пока будут переданы все данные, а потом выполнять какие-либо действия.
Обратите внимание на организацию передачи потоков данных для файла ресурсов
resource.json:
var stream = fs.createReadStream(‘./resource.json’)
// Событие Data вызывается после появления нового фрагмента данных
stream.on(‘data’, function (chunk) {
console.log(chunk)
})
stream.on(‘end’, function () {
console.log(‘finished’)
})
Событие data вызывается после появления нового фрагмента данных, а событие
end — после загрузки всех фрагментов кода. Фрагменты данных могут иметь
разные размеры (в зависимости от типа данных). Благодаря чтению потока данных
на низком уровне обеспечивается более эффективная обработка данных, чем
ожидание передачи всех данных в буфер памяти.
В Node также поддерживаются записываемые потоки данных, позволяющие
записывать фрагменты данных. Один из подобных потоков — объект ответа (res),
генерируемый в ответ на запрос к HTTP-серверу.
Считываемые и записываемые потоки могут соединяться, образуя каналы, как в
случае использования оператора | в языке написания сценариев оболочки. При этом
обеспечивается эффективный способ записи только что считанных данных без
ожидания считывания и сохранения всего ресурса.
Рассмотрим пример H TTP-сервера, взятый из предыдущего раздела. В данном
случае он будет передавать клиенту поток данных изображения:
var http = require(‘http’);
var fs = require(‘fs’);
http.createServer(function (req, res) {
res.writeHead(200, {‘Content-Type’: ‘image/png’});
// Передача по каналам из считываемого потока в записываемый
fs.createReadStream(‘./image.png’).pipe(res);
}).listen(3000);
console.log(‘Server running at http://localhost:3000/’);
При выполнении этого примера кода данные считываются из файла
(fs.createReadStream) и отсылаются (.pipe) клиенту (res) по мере считывания. Цикл
событий может обрабатывать другие события, пока данные передаются в потоке.
Node поддерживает описанный подход (когда механизм DIRTy предлагается по
умолчанию) на различных платформах, включая разные версии UN IX и Windows.
Базовая библиотека асинхронного ввода-вывода (libuv) была создана для того,
чтобы поддерживать универсальную методику обработки независимо от
родительской операционной системы. В результате обеспечивается упрощенный
перенос программ на другие устройства, на которых они могут выполняться.