تغيير يؤدي إلى عطل: طُرق المزامنة لـ AccessHandles

يوفر نظام الملفات الخاص بالمصدر إمكانية الوصول إلى نوع خاص من الملفات المحسّنة للغاية لتحقيق الأداء الأفضل، على سبيل المثال، من خلال إتاحة إمكانية الكتابة في مكانها الحصري لمحتوى الملف. يمكن للمطوّرين الوصول إلى هذه الملفات من خلال استدعاء createSyncAccessHandle()، وهي طريقة معروضة على عناصر FileSystemFileHandle. يؤدي هذا الطلب إلى FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle هو عنصر أساسي للملف يوفر إمكانية وصول عالية الأداء إلى الملفات المحلية. ومن بين حالات الاستخدام الرئيسية لهذا المعيار هي التطبيقات التي تنقل رمز C/C++ إلى Wasm، ومع ذلك، فإنّ المكالمات غير المتزامنة ليست متاحة بالكامل على Wasm حتى الآن، ويؤدي استخدام مكتبة Asyncify كبديل إلى خفض الأداء بشكل كبير. إنّ جعل كل طرق FileSystemSyncAccessHandle متزامنة تتوافق مع واجهة برمجة التطبيقات المتوافقة مع POSIX والمتوافقة مع Wasm للملف المتزامن، ما يجعل واجهة برمجة التطبيقات أكثر ملاءمةً مع تحقيق مكاسب كبيرة في الأداء.

الميزات الجديدة

يعرِض FileSystemSyncAccessHandle الطرق التالية التي كانت غير متزامنة، ولكنها متزامنة اعتبارًا من الإصدار 108 من Chromium.

  • 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 */