การเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ: วิธีการซิงค์สำหรับ AccessHandles

ระบบไฟล์ส่วนตัวต้นทางจะให้สิทธิ์เข้าถึงไฟล์ประเภทพิเศษที่ได้รับการเพิ่มประสิทธิภาพเพื่อประสิทธิภาพสูงสุด เช่น การให้สิทธิ์เขียนเนื้อหาของไฟล์ในตำแหน่งเดิมและสิทธิ์เขียนเฉพาะ นักพัฒนาแอปจะเข้าถึงไฟล์ดังกล่าวได้โดยการเรียกใช้ createSyncAccessHandle() ซึ่งเป็นเมธอดที่แสดงในออบเจ็กต์ FileSystemFileHandle การเรียกใช้นี้ส่งผลให้เกิด FileSystemSyncAccessHandle

FileSystemSyncAccessHandle เป็นไฟล์พื้นฐานที่ให้การเข้าถึงไฟล์ในเครื่องที่มีประสิทธิภาพ กรณีการใช้งานหลักอย่างหนึ่งคือแอปพลิเคชันที่พอร์ตโค้ด C/C++ ไปยัง Wasm อย่างไรก็ตาม Wasm ยังไม่รองรับการเรียกแบบไม่สอดคล้องกันโดยสมบูรณ์ และการใช้ไลบรารี Asyncify เป็นทางเลือกทำให้ประสิทธิภาพลดลงอย่างมาก การทำเมธอดทั้งหมดของ FileSystemSyncAccessHandle แบบซิงค์ให้ตรงกับ API ไฟล์แบบซิงค์ที่คล้าย POSIX ตามที่แอปพลิเคชันที่ใช้ Wasm คาดหวัง ทำให้ API ใช้งานง่ายขึ้นและมีประสิทธิภาพมากขึ้น

มีอะไรใหม่

FileSystemSyncAccessHandle แสดงเมธอดต่อไปนี้ซึ่งเคยเป็นแบบไม่พร้อมกัน แต่เป็นแบบพร้อมกันใน Chromium 108

  • truncate(newSize): ปรับขนาดไฟล์ที่เชื่อมโยงกับแฮนเดิลการเข้าถึงให้มีความยาว newSize ไบต์ หาก newSize ใหญ่กว่าขนาดไฟล์ปัจจุบัน ระบบจะเพิ่มไบต์ว่างในไฟล์ หากไม่ ระบบจะตัดไฟล์ให้สั้นลง
  • getSize(): แสดงผลขนาดของไฟล์ที่เชื่อมโยงกับแฮนเดิลการเข้าถึงเป็นไบต์
  • flush(): ตรวจสอบว่าเนื้อหาของไฟล์ที่เชื่อมโยงกับแฮนเดิลการเข้าถึงมีการแก้ไขทั้งหมดที่ทำผ่าน write()
  • close(): ล้างแฮนเดิลการเข้าถึงแล้วปิด การปิดแฮนเดิลการเข้าถึงจะปิดใช้การดำเนินการเพิ่มเติมกับแฮนเดิลนั้นและปลดล็อกรายการที่เชื่อมโยงกับแฮนเดิลการเข้าถึง
// In a `Worker`:
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('test', { create: true });
// `createSyncAccessHandle()` is still async.
const accessHandle = await fileHandle.createSyncAccessHandle();
// Both `read()` and `write()` were sync before.
accessHandle.read(/* ... */);
accessHandle.write(/* ... */);

// New: synchronous as of Chromium 108.
console.log(accessHandle.getSize());
accessHandle.truncate(123);
accessHandle.flush();
accessHandle.close();

สิ่งที่ต้องทำ

โปรดทราบว่าการเปลี่ยนวิธีการจากแบบไม่พร้อมกันเป็นแบบพร้อมกันเป็นการเปลี่ยนแปลงที่แสดงในเว็บซึ่งอาจทําให้เกิดความผิดพลาด แม้ว่าการใช้ await ในเมธอดแบบซิงค์จะใช้งานไม่ได้ แต่การใช้ Promise.then() จะใช้งานไม่ได้ หากใช้การเรียก then() กับผลลัพธ์ของเมธอดแบบไม่พร้อมกันก่อนหน้านี้ซึ่งตอนนี้เป็นแบบซิงโครนัสแล้ว คุณจะต้องเปลี่ยนโค้ด

// (✅) This won't break, but you better remove the superfluous `await`:
await accessHandle.flush();
// ✅ Correct:
accessHandle.flush();
// ⛔️ This will break, and you need to restructure your code:
accessHandle.flush().then(/* Follow-up code */);
// ✅ Correct:
accessHandle.flush();
/* Follow-up code */