Streams & I/O
ปัญหาของการโหลดข้อมูลทั้งหมดในครั้งเดียว
หัวข้อที่มีชื่อว่า “ปัญหาของการโหลดข้อมูลทั้งหมดในครั้งเดียว”ลองนึกภาพการอ่านไฟล์ Log ขนาด 4 GB ถ้าคุณโหลดข้อมูลทั้งหมดเข้า Memory ก่อน Node จะต้องจองพื้นที่ 4 GB ก่อนที่จะอ่านบรรทัดแรกได้ด้วยซ้ำ หากเครื่องมี RAM แค่ 2 GB กระบวนการจะพังก่อนที่จะเริ่มต้น
Stream แก้ปัญหานี้ด้วยการประมวลผลข้อมูล ทีละ chunk — คุณเริ่มอ่าน chunk แรกได้เลยขณะที่ chunk ที่เหลือยังมาไม่ถึง ทำให้ Memory ใช้คงที่ไม่ว่าแหล่งข้อมูลจะใหญ่แค่ไหน
แนวคิดเดียวกันนี้ใช้กับการเขียนด้วย แทนที่จะ Buffer Response ทั้งหมดใน Memory แล้วส่งในครั้งเดียว Stream จะส่ง chunk แต่ละชิ้นไปยังปลายทางทันทีที่ข้อมูลมาถึง
สี่ประเภทของ Stream
หัวข้อที่มีชื่อว่า “สี่ประเภทของ Stream”Node.js กำหนดประเภท Stream นามธรรมสี่ชนิดใน module node:stream:
| ประเภท | ทิศทาง | ตัวอย่าง |
|---|---|---|
Readable | ข้อมูลไหล ออก | fs.createReadStream, process.stdin |
Writable | ข้อมูลไหล เข้า | fs.createWriteStream, process.stdout |
Duplex | สองทิศทาง | TCP socket (net.Socket) |
Transform | สองทิศทางพร้อมแปลงข้อมูล | zlib.createGzip (บีบอัดระหว่างทาง) |
ทุก Stream ยังสืบทอดจาก EventEmitter ด้วย คลาสพื้นฐานของ Stream emit event มาตรฐาน (data, end, error, drain, finish) ที่คุณแนบ handler ได้
สิ่งที่โมดูลนี้จะสอน
หัวข้อที่มีชื่อว่า “สิ่งที่โมดูลนี้จะสอน”| บทเรียน | หัวข้อ |
|---|---|
| Readable Streams | events data/end/error, Readable.from, async iteration |
| Writable Streams | write(), end(), และ event drain |
| Pipe & Pipeline | เชื่อม Stream ด้วย .pipe() และ stream.pipeline() |
| Backpressure | คืออะไร สำคัญอย่างไร และ Pipeline จัดการอย่างไร |
ลองใช้ Stream ครั้งแรก
หัวข้อที่มีชื่อว่า “ลองใช้ Stream ครั้งแรก”Demo ด้านล่างใช้ Readable.from สร้าง Readable Stream จาก Array ของ String แล้วอ่านทีละ chunk ด้วย for await สังเกตว่าไม่มีการเก็บ Array ทั้งหมดไว้ใน Buffer — แต่ละรายการถูก yield เมื่อต้องการเท่านั้น
Needs the Node.js runtime — open in StackBlitz to run.