تغيير يؤدي إلى عطل: طُرق المزامنة لـ 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 */