عند إرسال البيانات إلى خادم ويب، ستفشل الطلبات أحيانًا. أُنشأها جون هنتر، الذي كان متخصصًا قد يكون السبب انقطاع الاتصال لدى المستخدم، أو بسبب تعطل الخادم؛ وفي كلتا الحالتين تحتاج غالبًا إلى محاولة إرسال الطلبات مرة أخرى في وقت لاحق.
واجهة BackgroundSync API الجديدة
هو الحل المثالي لهذه المشكلة. عندما يكتشف عامل خدمة
تعذّر طلب الشبكة، يمكن التسجيل لتلقي حدث sync
،
يتم تسليمه عندما يعتقد المتصفح أن الاتصال قد عاد.
لاحظ أنه يمكن تسليم حدث المزامنة حتى إذا غادر المستخدم
تطبيقه، مما يجعلها أكثر فعالية بكثير من الطريقة التقليدية
إعادة محاولة الطلبات التي أخفقت.
تم تصميم أداة Workbox Background Sync لتسهيل استخدام واجهة برمجة التطبيقات BackgroundSync API ودمجها مع وحدات Workbox الأخرى. أُنشأها جون هنتر، الذي كان متخصصًا أيضًا تنفيذ استراتيجية احتياطية للمتصفّحات التي لم تطبّق مزامنة الخلفية
تعذَّرت إعادة تشغيل المتصفّحات التي تتيح استخدام واجهة BackgroundSync API تلقائيًا. نيابةً عنك على الفاصل الزمني يديره المتصفِّح من المرجّح أن يتم استخدام خوارزمية الرقود الأسي بين محاولات إعادة التشغيل. في المتصفحات التي لا تتوافق مع واجهة برمجة تطبيقات BackgroundSync API في الأصل، فستقوم أداة Workbox Background Sync محاولة إعادة تشغيل تلقائيًا كلما تم بدء تشغيل عامل الخدمة.
الاستخدام الأساسي
أسهل طريقة لاستخدام ميزة "مزامنة الخلفية" هي استخدام Plugin
الذي
إضافة الطلبات التي تعذّر تنفيذها تلقائيًا إلى قائمة الانتظار وإعادة المحاولة عند sync
يتم تنشيط الأحداث.
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
maxRetentionTime: 24 * 60, // Retry for max of 24 Hours (specified in minutes)
});
registerRoute(
/\/api\/.*\/*.json/,
new NetworkOnly({
plugins: [bgSyncPlugin],
}),
'POST'
);
انضمام "BackgroundSyncPlugin
" إلى الكرة
fetchDidFail
معاودة الاتصال بالمكون الإضافي،
لا يتم استدعاء fetchDidFail
إلا في حال وجود استثناء، وذلك على الأرجح بسبب
إلى تعطُّل الشبكة. وهذا يعني أنّه لن تتم إعادة محاولة معالجة الطلبات إذا كانت هناك
تم تلقي الرد
حالة الخطأ 4xx
أو 5xx
.
إذا أردت إعادة محاولة تنفيذ كل الطلبات التي تؤدي إلى ظهور حالة 5xx
مثلاً،
يمكنك القيام بذلك عن طريق
إضافة المكون الإضافي fetchDidSucceed
على استراتيجيتك:
const statusPlugin = {
fetchDidSucceed: ({response}) => {
if (response.status >= 500) {
// Throwing anything here will trigger fetchDidFail.
throw new Error('Server error.');
}
// If it's not 5xx, use the response as-is.
return response;
},
};
// Add statusPlugin to the plugins array in your strategy.
الاستخدام المتقدّم
توفّر أيضًا Workbox Background Sync أيضًا فئة Queue
، التي يمكنك
لإنشاء مثيل وإضافة الطلبات التي أخفقت إلى. يتم تخزين الطلبات التي تعذّر تنفيذها
في IndexedDB
وتتم إعادة المحاولة عندما يعتقد المتصفح أنه قد تمت استعادة الاتصال (أي
عند استلام حدث المزامنة).
إنشاء قائمة انتظار
يجب إنشاء قائمة انتظار مزامنة خلفية لصندوق العمل باستخدام اسم قائمة انتظار (والذي يجب أن يكون فريدًا المصدر):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
يُستخدم اسم قائمة الانتظار كجزء من اسم العلامة التي تحصل
register()
بواسطة العالم
SyncManager
من المهم
يُستخدم أيضًا باعتباره
Object Store لـ
قاعدة بيانات IndexedDB.
إضافة طلب إلى قائمة الانتظار
بعد إنشاء مثيل قائمة الانتظار، يمكنك إضافة الطلبات التي أخفقت إليها.
أضفت الطلب الذي تعذّر تنفيذه من خلال استدعاء طريقة .pushRequest()
. على سبيل المثال:
ترصد التعليمة البرمجية التالية أي طلبات أخفقت وتضيفها إلى قائمة الانتظار:
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
self.addEventListener('fetch', event => {
// Add in your own criteria here to return early if this
// isn't a request that should use background sync.
if (event.request.method !== 'POST') {
return;
}
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({request: event.request});
return error;
}
};
event.respondWith(bgSyncLogic());
});
وبعد إضافته إلى قائمة الانتظار، تتم إعادة محاولة الطلب تلقائيًا عند
يتلقّى مشغّل الخدمات حدث sync
(الذي يحدث عندما يبدأ المتصفّح)
يعتقد أنه تمت استعادة الاتصال). المتصفحات التي لا تدعم
ستعيد واجهة برمجة التطبيقات BackgroundSync API قائمة الانتظار في كل مرة يتم فيها تشغيل عامل الخدمة
البدء. يتطلب ذلك أن تكون الصفحة التي تتحكم في عامل الخدمة
قيد التشغيل، لذلك لن تكون بنفس القدر من الفعالية.
اختبار المزامنة في الخلفية في Workbox
للأسف، كان اختبار BackgroundSync غير واضح وصعب إلى حد ما لعدة أسباب.
أفضل طريقة لاختبار عملية التنفيذ هي اتّباع الخطوات التالية:
- حمِّل صفحة وسجِّل مشغّل الخدمات.
- أوقِف شبكة جهاز الكمبيوتر أو أوقِف خادم الويب.
- لا تستخدم أدوات Chrome DEVTOOL بلا إنترنت. مربع الاختيار بلا اتصال في لا تؤثر "أدوات مطوري البرامج" إلا في الطلبات الواردة من الصفحة. طلبات مشغّل الخدمات الاستمرار في المضي قدمًا.
- أدخِل طلبات الشبكة التي يجب وضعها في قائمة الانتظار باستخدام Workbox Background Sync.
- يمكنك التحقق من وضع الطلبات في قائمة الانتظار من خلال مراجعة
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
- يمكنك التحقق من وضع الطلبات في قائمة الانتظار من خلال مراجعة
- الآن فعِّل الشبكة أو خادم الويب.
فرض حدث
sync
مبكر من خلال الانتقال إلىChrome DevTools > Application > Service Workers
، مع إدخال اسم العلامةworkbox-background-sync:<your queue name>
حيث يجب أن يكون<your queue name>
اسم قائمة الانتظار التي قمت بتعيينها، ثم النقر فوق "مزامنة" .سترى طلبات الشبكة تمرّ عبر الطلبات التي تعذّر تنفيذها من المفترض أن تكون بيانات IndexedDB فارغة نظرًا لأن الطلبات قد تمت تمت إعادة التشغيل بنجاح.
الأنواع
BackgroundSyncPlugin
صف ينفّذ معاودة الاتصال لمراحل نشاط fetchDidFail
. هذا يجعل من
كانت إضافة الطلبات التي أخفقت إلى قائمة انتظار المزامنة في الخلفية أسهل.
أماكن إقامة
-
الدالة الإنشائية
فراغ
تبدو دالة
constructor
كما يلي:(name: string, options?: QueueOptions) => {...}
-
الاسم
سلسلة
يمكنك الاطّلاع على
workbox-background-sync.Queue
. للحصول على تفاصيل حول المعاملات. -
الخيارات
QueueOptions اختيارية
-
returns
-
Queue
فئة لإدارة عملية تخزين الطلبات التي تعذّر تنفيذها في IndexedDB وإعادة المحاولة لاحقًا. يمكن مراقبة جميع أجزاء عملية التخزين وإعادة التشغيل عبر مع معاودة الاتصال.
أماكن إقامة
-
الدالة الإنشائية
فراغ
يتم إنشاء مثيل لقائمة الانتظار بالخيارات المحددة
تبدو دالة
constructor
كما يلي:(name: string, options?: QueueOptions) => {...}
-
الاسم
سلسلة
الاسم الفريد لقائمة الانتظار هذه. يجب أن يكون هذا الاسم فريدة لأنها تُستخدم لتسجيل أحداث المزامنة وطلبات التخزين في IndexedDB الخاص بهذا المثيل. سيحدث خطأ إذا تم اكتشاف اسم مكرر.
-
الخيارات
QueueOptions اختيارية
-
returns
-
-
الاسم
سلسلة
-
getAll
فراغ
تعرض جميع الإدخالات التي لم تنتهِ صلاحيتها (لكل
maxRetentionTime
). وتتم إزالة أي إدخالات منتهية الصلاحية من قائمة الانتظار.تبدو دالة
getAll
كما يلي:() => {...}
-
returns
Promise<QueueEntry[]>
-
-
popRequest
فراغ
إزالة وإعادة الطلب الأخير في قائمة الانتظار (بالإضافة إلى الطابع الزمني وأي بيانات وصفية). يظهر العنصر المعروض على النحو التالي:
{request, timestamp, metadata}
تبدو دالة
popRequest
كما يلي:() => {...}
-
returns
Promise<QueueEntry>
-
-
pushRequest
فراغ
تخزين الطلب الذي تم تمريره في IndexedDB (مع طابعه الزمني وأي بيانات التعريف) في نهاية قائمة الانتظار.
تبدو دالة
pushRequest
كما يلي:(entry: QueueEntry) => {...}
-
الإدخال
QueueEntry
-
returns
وعود <باطلة>
-
-
registerSync
فراغ
يتم تسجيل حدث مزامنة باستخدام علامة فريدة لهذا المثيل.
تبدو دالة
registerSync
كما يلي:() => {...}
-
returns
وعود <باطلة>
-
-
replayRequests
فراغ
تكرار كل طلب في قائمة الانتظار مع محاولة استرجاعه في حالة إخفاق أي طلب في إعادة جلبه، يتم إعادته إلى الموضع نفسه في قائمة الانتظار (التي تسجّل إعادة محاولة لحدث المزامنة التالي).
تبدو دالة
replayRequests
كما يلي:() => {...}
-
returns
وعود <باطلة>
-
-
shiftRequest
فراغ
إزالة الطلب الأول في قائمة الانتظار وإرجاعه (بالإضافة إلى الطابع الزمني وأي بيانات وصفية). يظهر العنصر المعروض على النحو التالي:
{request, timestamp, metadata}
تبدو دالة
shiftRequest
كما يلي:() => {...}
-
returns
Promise<QueueEntry>
-
-
الحجم
فراغ
تعرض عدد الإدخالات المتوفّرة في قائمة الانتظار. يُرجى العلم أنّ الإدخالات المنتهية الصلاحية (لكل
maxRetentionTime
) يتم تضمينها أيضًا في هذا العدد.تبدو دالة
size
كما يلي:() => {...}
-
returns
Promise<number>
-
-
unshiftRequest
فراغ
تخزين الطلب الذي تم تمريره في IndexedDB (مع طابعه الزمني وأي بيانات التعريف) في بداية قائمة الانتظار.
تبدو دالة
unshiftRequest
كما يلي:(entry: QueueEntry) => {...}
-
الإدخال
QueueEntry
-
returns
وعود <باطلة>
-
QueueOptions
أماكن إقامة
-
forceSyncFallback
قيمة منطقية اختيارية
-
maxRetentionTime
الرقم اختياري
-
onSync
OnSyncCallback اختياري
QueueStore
هي فئة لإدارة طلبات التخزين من قائمة انتظار في IndexedDB، الفهرسة حسب اسم قائمة الانتظار للوصول إليها بسهولة أكبر.
لن يحتاج معظم المطوّرين إلى الوصول إلى هذه الفئة مباشرةً. يتعرض لحالات الاستخدام المتقدمة.
أماكن إقامة
-
الدالة الإنشائية
فراغ
يتم ربط هذا المثيل بمثيل قائمة الانتظار، بحيث يمكن المحددة باسم قائمة الانتظار.
تبدو دالة
constructor
كما يلي:(queueName: string) => {...}
-
queueName
سلسلة
-
returns
-
-
deleteEntry
فراغ
يؤدي هذا الإجراء إلى حذف إدخال المعرّف المحدّد.
تحذير: لا تضمن هذه الطريقة أن ينتمي الإدخال المحذوف إلى هذا قائمة انتظار (أي تطابق
queueName
) لكن هذا القيد مقبول لأنّ هذه الفئة غير علنية. سيؤدي فحص إضافي إلى هذه الطريقة أبطأ مما ينبغي.تبدو دالة
deleteEntry
كما يلي:(id: number) => {...}
-
id
الرقم
-
returns
وعود <باطلة>
-
-
getAll
فراغ
إرجاع جميع الإدخالات في المتجر المطابقة لـ
queueName
.تبدو دالة
getAll
كما يلي:() => {...}
-
returns
Promise<QueueStoreEntry[]>
-
-
popEntry
فراغ
لإزالة الإدخال الأخير وإعادة إدخاله في قائمة الانتظار المطابقة مع
queueName
.تبدو دالة
popEntry
كما يلي:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
pushEntry
فراغ
يمكنك إلحاق آخر إدخال في قائمة الانتظار.
تبدو دالة
pushEntry
كما يلي:(entry: UnidentifiedQueueStoreEntry) => {...}
-
الإدخال
UnidentifiedQueueStoreEntry
-
returns
وعود <باطلة>
-
-
shiftEntry
فراغ
لإزالة الإدخال الأول في قائمة الانتظار المطابقة مع
queueName
وعرضه.تبدو دالة
shiftEntry
كما يلي:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
الحجم
فراغ
تعرض عدد الإدخالات في المتجر المطابقة لـ
queueName
.تبدو دالة
size
كما يلي:() => {...}
-
returns
Promise<number>
-
-
unshiftEntry
فراغ
يُرجى إضافة الإدخال أولاً في قائمة الانتظار.
تبدو دالة
unshiftEntry
كما يلي:(entry: UnidentifiedQueueStoreEntry) => {...}
-
الإدخال
UnidentifiedQueueStoreEntry
-
returns
وعود <باطلة>
-
StorableRequest
يشير ذلك المصطلح إلى فئة لتسهيل ترتيب الطلبات وإلغاء تسلسلها. يمكن تخزينها في IndexedDB.
لن يحتاج معظم المطوّرين إلى الوصول إلى هذه الفئة مباشرةً. يتعرض لحالات الاستخدام المتقدمة.
أماكن إقامة
-
الدالة الإنشائية
فراغ
تقبل كائن بيانات الطلب الذي يمكن استخدامه لإنشاء
Request
ولكن يمكن أيضًا تخزينها في IndexedDB.تبدو دالة
constructor
كما يلي:(requestData: RequestData) => {...}
-
requestData
RequestData
كائن بيانات الطلب الذي يتضمن
url
بالإضافة إلى أي خصائص ذات صلة بـ [requestInit]https://fetch.spec.whatwg.org/#requestinit
-
returns
-
-
استنساخ
فراغ
تنشئ نسخة طبق الأصل من المثيل وتعرضها بشكل عميق.
تبدو دالة
clone
كما يلي:() => {...}
-
returns
-
-
toObject
فراغ
لعرض نسخة طبق الأصل من عنصر
_requestData
للمثيلات.تبدو دالة
toObject
كما يلي:() => {...}
-
returns
RequestData
-
-
toRequest
فراغ
تحويل هذا المثيل إلى طلب.
تبدو دالة
toRequest
كما يلي:() => {...}
-
returns
الطلب
-
-
fromRequest
فراغ
تحويل كائن طلب إلى كائن عادي يمكن تنظيمه استنساخ أو مزود بسلاسل JSON.
تبدو دالة
fromRequest
كما يلي:(request: Request) => {...}
-
طلب
الطلب
-
returns
Promise<StorableRequest>
-