ออบเจ็กต์ที่ถ่ายโอนได้
ย้ายข้อมูลอย่างมีประสิทธิภาพโดยไม่ต้องคัดลอก
ออบเจ็กต์ที่ถ่ายโอนได้ เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ต้นทุนของการโคลน
การโคลนแบบมีโครงสร้างจะคัดลอกข้อมูลทีละไบต์ สำหรับ buffer ขนาดใหญ่ เช่น รูปภาพ เสียง และอาร์เรย์ขนาดใหญ่ การคัดลอกนี้ช้าและทำให้ใช้หน่วยความจำเพิ่มเป็นสองเท่า ออบเจ็กต์ที่โอนย้ายได้แก้ปัญหานี้ด้วยการย้ายความเป็นเจ้าของแทนการคัดลอก
สิ่งที่โอนได้
มีออบเจ็กต์เพียงบางชนิดเท่านั้นที่โอนได้ โดยชนิดสำคัญที่สุดคือ ArrayBuffer ชนิดอื่น ๆ ได้แก่ MessagePort ImageBitmap และ OffscreenCanvas
ArrayBuffer— หน่วยความจำไบนารีดิบMessagePort— ปลายทางของช่องสัญญาณImageBitmap— ข้อมูลรูปภาพที่ถอดรหัสแล้ว
รายการโอนย้าย
postMessage รับอาร์กิวเมนต์ตัวที่สองเป็นรายการออบเจ็กต์ที่โอนย้ายได้ ออบเจ็กต์ในรายการนี้จะถูกย้าย ไม่ใช่คัดลอก
const buffer = new ArrayBuffer(1024 * 1024); // 1 MB
worker.postMessage(buffer, [buffer]); // transfer itความเป็นเจ้าของถูกย้าย
หลังการโอน ฝั่งผู้ส่งจะใช้ buffer ต่อไม่ได้ เพราะ buffer จะถูกถอดการเชื่อมโยง (byteLength เป็น 0) ฝั่งผู้รับจะเป็นเจ้าของหน่วยความจำพื้นฐานเดียวกัน โดยไม่มีการคัดลอก
const buffer = new ArrayBuffer(8);
worker.postMessage(buffer, [buffer]);
console.log(buffer.byteLength); // 0 - now detachedการโอนอาร์เรย์แบบกำหนดชนิด
คุณต้องโอน ArrayBuffer ที่อยู่เบื้องหลังอาร์เรย์แบบกำหนดชนิดผ่านคุณสมบัติ .buffer ตัว view เองโอนไม่ได้ แต่ buffer ของตัว view โอนได้
const data = new Float64Array(100000);
worker.postMessage(data, [data.buffer]);
// data is now detached on this side.การรับข้อมูลที่โอนมา
ฝั่งผู้รับอ่านออบเจ็กต์ที่โอนมาจาก event.data ได้เหมือนกับข้อความที่ผ่านการโคลนทุกประการ ความแตกต่างมีเพียงว่าไม่มีการคัดลอกเกิดขึ้น
// worker.js
self.onmessage = (e) => {
const buffer = e.data; // we now own this memory
const view = new Uint8Array(buffer);
view[0] = 255;
};การส่งผลลัพธ์กลับ
หลังประมวลผลแล้ว worker สามารถโอน buffer กลับมาได้โดยไม่ต้องคัดลอกอีกครั้ง ทำให้ความเป็นเจ้าของกลับคืนสู่เธรดหลัก
// worker.js
self.onmessage = (e) => {
const buffer = e.data;
// ...process the bytes...
self.postMessage(buffer, [buffer]); // transfer back
};ประสิทธิภาพของการโอนเทียบกับการโคลน
สำหรับข้อมูลขนาดไม่กี่กิโลไบต์ ความแตกต่างแทบไม่มีนัยสำคัญ แต่สำหรับข้อมูลไบนารีขนาดหลายเมกะไบต์ การโอนจะเร็วกว่าอย่างเห็นได้ชัดและป้องกันการใช้หน่วยความจำที่พุ่งขึ้น ควรเลือกใช้กับ buffer ขนาดใหญ่
การหลีกเลี่ยงข้อผิดพลาดจากการใช้หลังการโอน
ข้อผิดพลาดที่พบบ่อยคือการอ่าน buffer หลังจากโอนไปแล้ว ให้ถือว่า buffer หมดสภาพทันทีที่ปรากฏในรายการโอนย้าย
worker.postMessage(buffer, [buffer]);
// BUG: buffer is detached here; this reads zero length.
// const len = buffer.byteLength; // 0การรวมข้อมูลที่โคลนและโอนย้าย
คุณสามารถส่งออบเจ็กต์ที่มี buffer อยู่ภายใน แล้วโอนเฉพาะ buffer นั้นได้ ออบเจ็กต์จะถูกโคลน ส่วน buffer ที่ระบุไว้จะถูกย้าย
const msg = { type: 'frame', pixels: buffer };
worker.postMessage(msg, [buffer]);
// msg.type is cloned; buffer is transferred.ควรใช้การโอนเมื่อใด
ใช้ออบเจ็กต์ที่โอนย้ายได้กับการประมวลผลรูปภาพ เสียง และวิดีโอ การคำนวณเชิงตัวเลขขนาดใหญ่ และกระบวนการที่ย้ายข้อมูลไบนารีก้อนใหญ่ระหว่างเธรด สำหรับข้อมูลขนาดเล็กที่มีลักษณะเหมือน JSON การโคลนตามปกติจะง่ายกว่าและเพียงพอ
ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับออบเจ็กต์ที่โอนย้ายได้
สรุป
คุณได้เรียนรู้ออบเจ็กต์ที่โอนย้ายได้:
- ส่งรายการโอนย้ายเป็นอาร์กิวเมนต์ตัวที่สองให้กับ
postMessage ArrayBufferและออบเจ็กต์อีกไม่กี่ชนิดจะถูกย้ายแทนการคัดลอก- buffer ของฝั่งผู้ส่งจะถูกถอดการเชื่อมโยงหลังจากนั้น
- โอนอาร์เรย์แบบกำหนดชนิดผ่าน
.buffer - ใช้กับข้อมูลไบนารีขนาดใหญ่ และใช้การโคลนกับข้อมูลขนาดเล็ก
ถัดไปคือกรณีการใช้งานและข้อจำกัดของ worker
คำถามที่พบบ่อย
บทเรียน “ออบเจ็กต์ที่ถ่ายโอนได้” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ออบเจ็กต์ที่ถ่ายโอนได้” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “ออบเจ็กต์ที่ถ่ายโอนได้”
ย้ายข้อมูลอย่างมีประสิทธิภาพโดยไม่ต้องคัดลอก คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “ออบเจ็กต์ที่ถ่ายโอนได้” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม
ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้าง Web Worker
- การส่งข้อความด้วย postMessage
- ออบเจ็กต์ที่ถ่ายโอนได้
- กรณีใช้งานและข้อจำกัด