Skip to main content
Практика завдань

Що таке streams у Node.js?

Node.js Потоки

Потоки є однією з найпотужніших функцій Node.js. Вони дозволяють вам обробляти дані частинами (по шматочках), а не завантажувати все в пам'ять одночасно — це необхідно для роботи з великими файлами, мережевими даними або обробкою в реальному часі.


Чому Потоки?

js
// БЕЗ потоків — завантажує весь файл в пам'ять ❌ const data = fs.readFileSync('huge-file.mp4'); // 4 ГБ в ОП! res.end(data); // З ПОТОКАМИ — обробляє частинами ✅ fs.createReadStream('huge-file.mp4').pipe(res);

Чотири Типи Потоків

ТипОписПриклад
ReadableДжерело данихfs.createReadStream(), http.IncomingMessage
WritableПризначення для данихfs.createWriteStream(), http.ServerResponse
DuplexІ читабельний, і записуванийnet.Socket, zlib.createGzip()
TransformДуплекс, що модифікує даніcrypto.createCipher(), zlib

Читабельний Потік

js
const fs = require('fs'); const readable = fs.createReadStream('./large-file.txt', { encoding: 'utf8', highWaterMark: 64 * 1024 // 64КБ шматки }); readable.on('data', chunk => { console.log(`Отримано ${chunk.length} байт`); }); readable.on('end', () => console.log('Читання завершено')); readable.on('error', err => console.error(err));

Записувальний Потік

js
const fs = require('fs'); const writable = fs.createWriteStream('./output.txt'); writable.write('Привіт, '); writable.write('Потоки!'); writable.end(' '); writable.on('finish', () => console.log('Запис завершено'));

pipe() — З'єднання Потоків

pipe() автоматично обробляє зворотний тиск і з'єднує читабельний з записувальним:

js
const fs = require('fs'); const zlib = require('zlib'); // Читати → Стиснути → Записати (все в потоковому режимі, низька пам'ять) fs.createReadStream('input.txt') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('input.txt.gz'));

pipeline() — Сучасний підхід (Node.js 10+)

js
const { pipeline } = require('stream/promises'); const fs = require('fs'); const zlib = require('zlib'); await pipeline( fs.createReadStream('input.txt'), zlib.createGzip(), fs.createWriteStream('input.txt.gz') ); // Автоматично обробляє помилки та очищення

Потік Перетворення (Користувацький)

js
const { Transform } = require('stream'); const upperCaseTransform = new Transform({ transform(chunk, encoding, callback) { this.push(chunk.toString().toUpperCase()); callback(); } }); process.stdin.pipe(upperCaseTransform).pipe(process.stdout);

Зворотний Тиск

Коли споживач повільніший за виробника, Node.js автоматично призупиняє читання:

js
const readable = fs.createReadStream('./huge.bin'); const writable = fs.createWriteStream('./copy.bin'); readable.on('data', chunk => { const canContinue = writable.write(chunk); if (!canContinue) { readable.pause(); // зупинити читання, поки записувальний не спустошиться writable.once('drain', () => readable.resume()); } });

pipe() автоматично обробляє зворотний тиск.


Резюме

Використовуйте потоки, коли:

  • Обробляєте великі файли (відео, журнали, CSV)
  • Працюєте з HTTP запитами/відповідями
  • Створюєте потоки даних в реальному часі
  • Зменшуєте використання пам'яті вашого додатку

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань