ดูเหมือนหลายๆ คนจะไม่เข้าใจว่า NodeJS แบบเธรดเดี่ยวสามารถแข่งขันกับแบ็กเอนด์แบบมัลติเธรดได้อย่างไร
หากต้องการทราบว่าเหตุใด เราต้องเข้าใจว่าจริงๆ แล้ว Nodejs เป็นแบบเธรดเดียวหมายความว่าอย่างไร
เดิมที JavaScript นั้นถูกสร้างขึ้นเพื่อทำสิ่งง่ายๆ เช่น ตรวจสอบแบบฟอร์ม ตอบกลับ ฯลฯ จนถึงปี 2009 Ryan Dahl ผู้สร้าง Node.js ทำให้สามารถเขียนโค้ดฝั่งเซิร์ฟเวอร์โดยใช้ JavaScript ได้
ภาษาฝั่งเซิร์ฟเวอร์ที่รองรับมัลติเธรดมีโครงสร้างและโครงสร้างที่หลากหลายสำหรับการซิงโครไนซ์ระหว่างเธรดและคุณสมบัติเชิงเธรดอื่น ๆ
การสนับสนุนสิ่งเหล่านี้หมายความว่า JavaScript จะต้องเปลี่ยนภาษาทั้งหมด ซึ่งขัดแย้งกับแนวคิดของผู้สร้าง JavaScript ดังนั้น เพื่อที่จะสนับสนุนการทำงานแบบมัลติเธรดใน JavaScript ล้วนๆ Dahl จึงต้องสร้างวิธีแก้ปัญหา มาดูกัน!
Node.js ทำงานอย่างไร
Node.js ใช้เธรดสองประเภท: เธรดหลักซึ่งจัดการโดยลูปเหตุการณ์ และเธรดรองหลายเธรดในกลุ่มเธรดผู้ปฏิบัติงาน
กลไกของ Event Loop Node.js สำหรับจัดการการดำเนินการ I/O ที่ไม่บล็อก แม้ว่า JavaScript จะเป็นแบบเธรดเดียวก็ตาม จะถ่ายการดำเนินการไปยังเคอร์เนลของระบบเมื่อเป็นไปได้ เมื่อการดำเนินการ JavaScript บล็อกเธรด การวนรอบเหตุการณ์ก็จะถูกบล็อกเช่นกัน
พูลผู้ปฏิบัติงาน คือโมเดลการดำเนินการที่สร้างและประมวลผลเธรดที่แยกจากกัน จากนั้นรันงานพร้อมกันและส่งผลลัพธ์กลับไปยังลูปเหตุการณ์ ลูปเหตุการณ์จะใช้ผลลัพธ์ดังกล่าวเพื่อดำเนินการโทรกลับที่ให้มา
โดยพื้นฐานแล้ว พูลผู้ปฏิบัติงานจะจัดการกับการดำเนินการ I/O แบบอะซิงโครนัส โดยพื้นฐานแล้วจะมีปฏิสัมพันธ์กับดิสก์ระบบและเครือข่าย บางโมดูลใช้พูลผู้ปฏิบัติงานนอกกรอบ เช่น fs (I/O-heavy) หรือ crypto (CPU-heavy) พูลผู้ปฏิบัติงานถูกนำไปใช้ใน libuv ซึ่งทำให้เกิดความล่าช้าเล็กน้อยแต่แทบไม่มีนัยสำคัญเลย เมื่อโหนดต้องการถ่ายโอนข้อมูลภายในระหว่าง JavaScript และ C++
หลังจากเข้าใจความหมายของลูปเหตุการณ์และกลุ่มงานแล้ว ลองดูโค้ดต่อไปนี้:
ในโค้ดข้างต้น เราไม่ต้องรอเหตุการณ์พร้อมกัน เรามอบหมายงานการอ่านไฟล์ให้กับกลุ่มผู้ปฏิบัติงานและเรียกใช้ฟังก์ชันที่ให้มาพร้อมกับผลลัพธ์ เนื่องจากพูลผู้ปฏิบัติงานมีเธรดของตัวเอง ลูปเหตุการณ์จึงสามารถดำเนินการต่อไปได้ตามปกติในขณะที่อ่านไฟล์
ฉันขอแนะนำให้คุณรู้จัก: worker_threads
ด้วยการเปิดตัว Node.js 10.5.0 worker_threads ปรากฏขึ้น รองรับการสร้างแอปพลิเคชันแบบมัลติเธรดอย่างง่ายใน JavaScript
worker_threads เป็นแพ็คเกจโมดูล nodejs ผู้ปฏิบัติงานเธรดคือโค้ดชิ้นหนึ่ง (โดยปกติจะนำมาจากไฟล์) ที่สร้างขึ้นในเธรดที่แยกจากกัน
สิ่งสำคัญคือต้องทราบว่าคำว่า thread worker, worker และ thread มักใช้สลับกันได้ พวกเขาทั้งหมดอ้างถึงสิ่งเดียวกัน
เธรดผู้ปฏิบัติงานใน Node.js มีประโยชน์สำหรับการทำงาน JavaScript จำนวนมาก ด้วยความช่วยเหลือของเธรด ผู้ปฏิบัติงานสามารถเรียกใช้โค้ด JavaScript แบบขนานได้อย่างง่ายดาย ทำให้รวดเร็วและมีประสิทธิภาพมากขึ้น เราสามารถทำงานหนักๆ ได้โดยไม่รบกวนเธรดหลัก
เธรดผู้ปฏิบัติงานไม่ได้ถูกนำมาใช้ใน Node.js เวอร์ชันเก่า ดังนั้นก่อนอื่นให้อัปเดต Node.js ของคุณเพื่อเริ่มต้น
ตอนนี้ให้สร้างสองไฟล์เพื่อใช้เธรดดังนี้:
ชื่อไฟล์: worker.js
const { workerData, parentPort } = need('worker_threads'); console.log(`เขียนถึงวิธีที่ ${workerData} ต้องการทำใจให้สบายกับหนุ่มใหญ่`); parentPort.postMessage({ ชื่อไฟล์: workerData, สถานะ: 'เสร็จสิ้น' });
ชื่อไฟล์: index.js
const { ผู้ปฏิบัติงาน } = ต้องการ ('worker_threads'); const runSerice = (ข้อมูลผู้ปฏิบัติงาน) => { คืนสัญญาใหม่ ((แก้ไข, ปฏิเสธ) => { ผู้ปฏิบัติงาน const = ผู้ปฏิบัติงานใหม่ ('./worker.js', { workerData }); worker.on('ข้อความ', แก้ไข); worker.on('ข้อผิดพลาด', ปฏิเสธ); worker.on('exit', (รหัส) => { ถ้า (รหัส !== 0) ปฏิเสธ (ข้อผิดพลาดใหม่ (`เธรดผู้ปฏิบัติงานหยุดทำงานด้วยรหัสออก ${code}`)); - - - const ทำงาน = async () => { ผลลัพธ์ const = รอ runSerice ('Tunde Ednut'); console.log(ผลลัพธ์); - run().catch((err) => console.error(err));
เอาท์พุต: