0Pricing
JavaScript Academy · บทเรียน

ออบเจ็กต์ที่ถ่ายโอนได้

ย้ายข้อมูลอย่างมีประสิทธิภาพโดยไม่ต้องคัดลอก

ออบเจ็กต์ที่ถ่ายโอนได้ เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้าง Web Worker
  2. การส่งข้อความด้วย postMessage
  3. ออบเจ็กต์ที่ถ่ายโอนได้
  4. กรณีใช้งานและข้อจำกัด
← กลับไปที่ JavaScript Academy