Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що таке Transform stream?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Transform Stream** - особливий вид Duplex-потоку, що приймає дані на вхід, обробляє їх і видає змінений результат на вихід, наприклад стиснення (`zlib.createGzip()`) чи шифрування. **Ключове:** на відміну від звичайного Duplex, у Transform вхід і вихід пов'язані напряму - метод `_transform()` перетворює кожен chunk перед тим, як передати його далі через `.push()`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Transform Stream** - це особливий вид потоку в Node.js, що одночасно є **Readable** і **Writable**, але на відміну від звичайного `Duplex`, він **перетворює** дані, що проходять через нього. > Простіше кажучи: **Transform Stream = Duplex Stream + перетворення даних.** ## Концепція `Transform Stream` приймає вхідні дані → обробляє їх → видає змінений результат. Він використовується, коли потрібно **обробляти потік даних "на льоту"**, не чекаючи його завершення. ## Приклади вбудованих Transform Streams | Модуль | Приклад | Опис | |---|---|---| | `zlib` | `zlib.createGzip()` / `zlib.createGunzip()` | Стиснення й розпакування даних | | `crypto` | `crypto.createCipheriv()` / `createDecipheriv()` | Шифрування / дешифрування | | `stream` | `new stream.Transform()` | Створення власного трансформаційного потоку | | `readline` | Логічні перетворення тексту порядково | | ## Проста аналогія Уяви конвеєр: - на вхід подається потік рядків, - потік перетворює їх (наприклад, робить `toUpperCase()`), - і видає на вихід змінені дані. ## Приклад кастомного Transform Stream ```javascript const { Transform } = require('stream'); class UpperCaseTransform extends Transform { constructor(options) { super(options); } _transform(chunk, encoding, callback) { const transformed = chunk.toString().toUpperCase(); this.push(transformed); // передаємо результат далі callback(); // сигнал, що обробку завершено } } const upperCase = new UpperCaseTransform(); process.stdin.pipe(upperCase).pipe(process.stdout); ``` Тут: - `process.stdin` - потік введення (Readable), - `upperCase` - наш Transform-потік (змінює дані), - `process.stdout` - потік виведення (Writable). Усе, що ти введеш у консоль, виведеться великими літерами. ## Основні методи Transform Stream | Метод | Опис | |---|---| | `_transform(chunk, encoding, callback)` | Головний метод - перетворює вхідні дані | | `_flush(callback)` | Викликається, коли вхідний потік завершено - можна "допушити" залишки даних | | `.push(data)` | Передає оброблені дані у вихідний потік | ## Приклад із `_flush()` ```javascript class JSONLinesTransform extends Transform { constructor() { super({ readableObjectMode: true }); this.buffer = ''; } _transform(chunk, encoding, callback) { this.buffer += chunk.toString(); let lines = this.buffer.split('\n'); this.buffer = lines.pop(); // лишаємо останній неповний рядок for (const line of lines) { if (line.trim()) { this.push(JSON.parse(line)); } } callback(); } _flush(callback) { if (this.buffer.trim()) { this.push(JSON.parse(this.buffer)); } callback(); } } ``` Цей потік: - читає **рядки JSON** порядково, - перетворює їх на **об'єкти JavaScript**, - і передає далі як stream об'єктів. ## Типові сценарії використання Transform Streams | Задача | Приклад | |---|---| | Стиснення файлів | `fs.createReadStream('file.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('file.gz'))` | | Шифрування | `fs.createReadStream('data').pipe(crypto.createCipheriv(...)).pipe(fs.createWriteStream('data.enc'))` | | Форматування даних | JSON → CSV, XML → JSON тощо | | Логування / фільтрація / дебаунс | Потокове перетворення логів, HTTP-запитів, даних сенсорів | ## Різниця між Duplex і Transform | Властивість | Duplex | Transform | |---|---|---| | Читання й запис | Так | Так | | Перетворює дані | Ні | Так | | Вхід і вихід пов'язані | Ні | Так | | Приклад | TCP-сокет | gzip, cipher, JSON-парсер | ## Переваги Transform Stream - Асинхронна обробка потоку "на льоту" - Економія пам'яті - не потрібно тримати весь файл у RAM - Проста композиція (`pipe()`-ланцюжки) - Легко розширюється - можна писати власні перетворювачіДля рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.