Що таке Transform stream?
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()-ланцюжки) - Легко розширюється - можна писати власні перетворювачі
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.