Node.js Stream dengan naskah – beragampengetahuan – Beragampengetahuan
Node.js dikenal karena kemampuannya untuk menangani operasi I/O secara efisien, dan inti dari kemampuan ini terletak pada mengalir. Stream memungkinkan Anda untuk memproses potongan data demi sepotong, daripada memuat semuanya ke dalam memori sekaligus – dengan sempurna menangani file besar, permintaan jaringan, atau data waktu -nyata. Saat Anda memasangkan aliran dengan pengetikan kunci yang kuat dari TypeScript, Anda mendapatkan kombinasi yang kuat: kinerja konsisten dengan keamanan.
Dalam panduan ini, kami akan menyelami aliran Node.js, mengeksplorasi jenisnya, dan menelusuri contoh -contoh praktis menggunakan naskah. Apakah Anda seorang pemula Node.js atau penggemar TypeScript yang ingin meningkatkan, artikel ini dapat diperkenalkan.
Contents
Mengapa Stream Penting?
Gambar: Tugas Anda adalah memproses file log 50GB. Memuatnya sepenuhnya ke dalam memori akan menghabiskan sumber daya server, menghasilkan crash atau kinerja yang lambat. Stream menyelesaikan masalah ini dengan membiarkan Anda memproses data, seperti minum dari jerami alih -alih meremas kaleng galon.
Efisiensi inilah sebabnya stream adalah landasan Node.js, semuanya mulai dari operasi file hingga server HTTP. TypeScript meningkatkan ini dengan menambahkan definisi jenis, menangkap kesalahan pada waktu kompilasi dan meningkatkan keterbacaan kode. Mari kita gali dasar -dasar dan lihat bagaimana sinergi ini bekerja dalam praktik.
Empat Jenis Aliran
Node.js menyediakan empat jenis aliran utama, masing -masing dengan tujuan tertentu:
- Aliran yang dapat dibaca: Anda dapat membaca sumber data dari (mis., File, respons HTTP).
- Aliran yang dapat ditulis: Tujuan yang dapat Anda tulis (mis., File, permintaan http).
- Aliran dupleks: Dapat dibaca dan dapat ditulis (mis., Soket TCP).
- Mengubah aliran: Aliran dupleks khusus yang memodifikasi data ketika melewati data (seperti kompresi).
TypeScript meningkatkan fungsionalitas ini dengan memungkinkan kita untuk mendefinisikan antarmuka untuk data yang mengalir melaluinya. Mari kita hancurkan dengan contoh.
Siapkan lingkungan TypeMcript Anda
Sebelum kita menggali kode, pastikan Anda memiliki node.js dan naskah yang diinstal.
Buat proyek baru:
mkdir node-streams-typescript
cd node-streams-typescript
npm init -y
npm install typescript @types/node --save-dev
npx tsc --init
Perbarui tsconfig.json Anda untuk memasukkan:
"compilerOptions":
"target": "ES2020",
"module": "commonjs",
"strict": true,
"outDir": "./dist"
,
"include": ["src/**/*"]
Buat folder SRC dan mari kita mulai berkode!
Contoh 1: Membaca file dengan aliran yang dapat dibaca
Mari Baca Blok File Teks. Pertama, gunakan beberapa teks sampel untuk membuat file bernama data.txt (misalnya, “Halo, stream!”).
Sekarang, di src/readStream.ts:
import createReadStream from 'fs';
import Readable from 'stream';
const readStream: Readable = createReadStream('data.txt', encoding: 'utf8' );
readStream
.on('data', (chunk: string) =>
console.log('Chunk received:', chunk);
)
.on('end', () =>
console.log('Finished reading the file.');
)
.on('error', (err: Error) =>
console.error('Error:', err.message);
);
Jalankan:
npx tsc && node dist/readStream.js
Di sini, TypeScript memastikan bahwa blok menempel pada antarmuka blok kami dan bahwa event handler kesalahan mengharapkan jenis kesalahan. Streaming ini membaca data.txt (file default adalah 64kb) di blok dan mencatatnya.
Contoh 2: Tulis data dalam aliran yang dapat ditulis
Sekarang, mari kita tulis data ke file baru. Di src/writeStream.ts:
import createWriteStream from 'fs';
import Writable from 'stream';
const writeStream: Writable = createWriteStream('output.txt', encoding: 'utf8' );
const data: string[] = ['Line 1\n', 'Line 2\n', 'Line 3\n'];
data.forEach((line: string) =>
writeStream.write(line);
);
writeStream.end(() =>
console.log('Finished writing to output.txt');
);
writeStream.on('error', (err: Error) =>
console.error('Error:', err.message);
);
Kompilasi dan jalankan:
npx tsc && node dist/writeStream.js
Ini akan membuat output.txt dengan tiga baris. TypeScript memastikan bahwa garis adalah string dan memberikan penyelesaian otomatis untuk metode streaming.
Contoh 3: Pipa dengan aliran konversi
Pipa adalah tempat alirannya bersinar, menghubungkan aliran yang dapat dibaca ke aliran yang dapat ditulis. Mari tambahkan twist Mengubah Streaming teks kami.
Di src/transformstream.ts:
import createReadStream, createWriteStream from 'fs';
import Transform, TransformCallback from 'stream';
class UppercaseTransform extends Transform
_transform(chunk: Buffer, encoding: string, callback: TransformCallback): void
const upperChunk = chunk.toString().toUpperCase();
this.push(upperChunk);
callback();
const readStream = createReadStream('data.txt', encoding: 'utf8' );
const writeStream = createWriteStream('output_upper.txt');
const transformStream = new UppercaseTransform();
readStream
.pipe(transformStream)
.pipe(writeStream)
.on('finish', () =>
console.log('Transform complete! Check output_upper.txt');
)
.on('error', (err: Error) =>
console.error('Error:', err.message);
);
Jalankan:
npx tsc && node dist/transformStream.js
Ini membaca data.txt, mengubah teks menjadi huruf besar, dan kemudian menulisnya ke output_upper.txt.
Jenis panggilan balik transformasi TypeScript memastikan bahwa metode _transform kami diimplementasikan dengan benar.
Contoh 4: Kompres file dengan duplex stream
Mari kita selesaikan solusi yang lebih canggih: Gunakan modul zlib untuk mengompres file, yang menyediakan streaming dua sisi. Muncul dengan paket “@@type/node” yang kami instal sebelumnya.
Di src/compressstream.ts:
import createReadStream, createWriteStream from 'fs';
import createGzip from 'zlib';
import pipeline from 'stream';
const source = createReadStream('data.txt');
const destination = createWriteStream('data.txt.gz');
const gzip = createGzip();
pipeline(source, gzip, destination, (err: Error | null) =>
if (err)
console.error('Compression failed:', err.message);
return;
console.log('File compressed successfully! Check data.txt.gz');
);
Jalankan:
npx tsc && node dist/compressStream.js
Di sini, pipa memastikan penanganan dan pembersihan yang tepat. GZIP Stream mengompres data.txt ke data.txt.gz. Ketik inferensi naskah dapat membuat kode kami bersih dan aman.
Contoh 5: Streaming Respons HTTP
Aliran bersinar selama operasi jaringan. Mari kita gunakan AXIOS untuk mensimulasikan data streaming dari server HTTP. Instal:
npm install axios @types/axios
Di src/httpstream.ts:
import axios from 'axios';
import createWriteStream from 'fs';
import Writable from 'stream';
async function streamHttpResponse(url: string, outputFile: string): Promise<void>
const response = await axios(
method: 'get',
url,
responseType: 'stream',
);
const writeStream: Writable = createWriteStream(outputFile);
response.data.pipe(writeStream);
return new Promise((resolve, reject) =>
writeStream.on('finish', () =>
console.log(`Downloaded to $outputFile`);
resolve();
);
writeStream.on('error', (err: Error) =>
console.error('Download failed:', err.message);
reject(err);
);
);
streamHttpResponse('https://example.com', 'example.html').catch(console.error);
Jalankan:
npx tsc && node dist/httpStream.js
Ini akan mengalirkan contoh respons http (mis. Halaman web) contoh.html. TypeScript memastikan bahwa parameter URL dan outputFile adalah string dan yang menjanjikan pengetikan meningkatkan kejelasan.
Kami juga dapat menggunakan API fetch built-in node.js (tersedia sejak Node V18) atau perpustakaan seperti Node-Fetch, yang juga mendukung respons aliran, meskipun jenis aliran dapat bervariasi (stream web vs.node.js stream).
contoh:
const response = await fetch('https://example.com');
const writeStream = createWriteStream(outputFile);
response.body.pipe(writeStream);
Contoh 6: Pemrosesan Data Real-Time Menggunakan Stream yang Dapat Dibaca Kustom
Mari kita buat aliran khusus dan dapat dibaca untuk mensimulasikan data real-time seperti pembacaan sensor. Di src/customable.ts:
import Readable from 'stream';
class SensorStream extends Readable
private count: number = 0;
private max: number = 10;
constructor(options?: any)
super(options);
_read(): void
if (this.count < this.max)
const data = `Sensor reading $this.count: $Math.random() * 100\n`;
this.push(data);
this.count++;
else
this.push(null);
const sensor = new SensorStream( encoding: 'utf8' );
sensor
.on('data', (chunk: string) =>
console.log('Received:', chunk.trim());
)
.on('end', () =>
console.log('Sensor stream complete.');
)
.on('error', (err: Error) =>
console.error('Error:', err.message);
);
Jalankan:
npx tsc && node dist/customReadable.js
Ini menghasilkan 10 “pembacaan sensor” acak dan mengalirkannya. Pengetikan kelas untuk TypeScript memastikan bahwa implementasi kami konsisten dengan antarmuka yang dapat dibaca.
Contoh 7: Menghubungkan beberapa aliran transformasi
Mari kita konversi rantai untuk memproses teks secara bertahap: huruf besar, dan pra-sampel. Di src/chaintransform.ts:
import createReadStream, createWriteStream from 'fs';
import Transform, TransformCallback from 'stream';
class UppercaseTransform extends Transform
_transform(chunk: Buffer, encoding: string, callback: TransformCallback): void
this.push(chunk.toString().toUpperCase());
callback();
class TimestampTransform extends Transform
_transform(chunk: Buffer, encoding: string, callback: TransformCallback): void
const timestamp = new Date().toISOString();
this.push(`[$timestamp] $chunk.toString()`);
callback();
const readStream = createReadStream('data.txt', encoding: 'utf8' );
const writeStream = createWriteStream('output_chain.txt');
const upper = new UppercaseTransform();
const timestamp = new TimestampTransform();
readStream
.pipe(upper)
.pipe(timestamp)
.pipe(writeStream)
.on('finish', () =>
console.log('Chained transform complete! Check output_chain.txt');
)
.on('error', (err: Error) =>
console.error('Error:', err.message);
);
Jalankan:
npx tsc && node dist/chainTransform.js
Ini membaca data.txt, memanfaatkan data, menambahkan cap waktu, dan menulis hasilnya ke output_chain.txt. Modularitas aliran tampilan rantai transformasi.
Praktik terbaik untuk streaming di TypeScript
- Masukkan data Anda: Tentukan antarmuka blok untuk menangkap kesalahan jenis sedini mungkin.
- Penanganan kesalahan: Selalu lampirkan pendengar acara kesalahan untuk menghindari pengecualian yang tidak diobati.
- Gunakan pipa dengan bijak: Pipeline mengurangi pemrosesan acara manual dan meningkatkan keterbacaan.
- Tekanan balik: Untuk data besar, silakan memantau WriteStream.writable Highwatermark untuk menghindari mencapai tujuan Anda.
Kasus Penggunaan Dunia Nyata: Streaming Respons API
Bayangkan Anda sedang membangun API untuk streaming kumpulan data besar. Menggunakan Express dan Stream:
import express from 'express';
import Readable from 'stream';
const app = express();
app.get('/stream-data', (req, res) =>
const data = ['Item 1\n', 'Item 2\n', 'Item 3\n'];
const stream = Readable.from(data);
res.setHeader('Content-Type', 'text/plain');
stream.pipe(res);
);
app.listen(3000, () =>
console.log('Server running on port 3000');
);
Instal Ketergantungan (NPM Instal Express @Type/Express) dan jalankan. Kunjungi untuk melihat aliran data di browser Anda!
Tip Lanjutan: Tangani Tekanan Kembali
Tekan backsure terjadi ketika aliran yang dapat ditulis tidak dapat mengimbangi aliran yang dapat dibaca. Node.js akan secara otomatis menangani ini menggunakan pipa, tetapi Anda dapat memantau secara manual:
const writeStream = createWriteStream('large_output.txt');
if (!writeStream.write('data'))
console.log('Backpressure detected! Pausing...');
writeStream.once('drain', () =>
console.log('Resuming...');
);
Ini memastikan bahwa aplikasi Anda tetap responsif di bawah muat ulang.
Tindakan pencegahan untuk menggunakan tekanan balik: Saat menulis data dalam jumlah besar, aliran yang dapat dibaca dapat menghasilkan data lebih cepat daripada aliran yang dapat ditularkan. Saat pipa dan pipa secara otomatis menangani ini, jika ditulis secara manual, periksa apakah write () mengembalikan salah dan tunggu acara “tiriskan” sebelum menulis lebih banyak.
Selain itu, iterator asinkron (menunggu menunggu …) adalah alternatif modern untuk mengonsumsi aliran yang dapat dibaca, yang sering dapat menyederhanakan kode dibandingkan dengan menggunakan .on (‘data’) dan .on (‘end’).
contoh:
async function processStream(readable: Readable)
for await (const chunk of readable)
console.log('Chunk:', chunk);
console.log('Finished reading.');
Poin Lainnya:
Pastikan pembersihan sumber daya: Ini sangat penting ketika menyesuaikan implementasi aliran atau menggunakan stream.pipeline. Dalam skenario yang salah atau dalam aliran di mana sumber daya yang mendasarinya tidak perlu lagi dilepaskan dan mencegah kebocoran, stream.destroy () secara eksplisit dipanggil dalam skenario yang salah. Pipa aliran akan secara otomatis memproses aliran aliran.
Untuk kenyamanan: Mudah dibaca ketika Anda perlu membuat aliran dari iterasi yang ada (seperti array) atau proses memuncak asinkron. dari () biasanya merupakan cara termudah dan paling modern untuk melakukannya, dan kode boilerplate yang diperlukan untuk membuat kategori yang dapat dibaca khusus.
sebagai kesimpulan
Stream adalah game changers di node.js, dan naskah lebih lanjut meningkatkannya dengan memperkenalkan keamanan dan kejelasan tipe. Dari membaca file hingga mengonversi data secara real time, menguasai aliran membuka dunia dengan kemungkinan I/O yang efektif. Contoh -contoh di sini – membaca, menulis, mengubah, mengompresi dan streaming di atas HTTP – Gambar permukaan yang mungkin.
Coba pipa Anda sendiri: Coba streaming log, proses file CSV, atau bangun sistem obrolan langsung. Semakin banyak Anda menjelajah, semakin Anda menghargai fleksibilitas aliran.
rencana pengembangan website
metode pengembangan website
jelaskan beberapa rencana untuk pengembangan website, proses pengembangan website, kekuatan dan kelemahan bisnis pengembangan website
, jasa pengembangan website, tahap pengembangan website, biaya pengembangan website
#Node.js #Stream #dengan #naskah #beragampengetahuan