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

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

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