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

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

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

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

يعرِض 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 */