أحداث الدفع

لقد اطّلعت إلى الآن على كيفية اشتراك مستخدم وإرسال رسالة فورية إليه. الخطوة التالية هي تلقّي هذه الرسالة الفورية على جهاز المستخدم وعرض إشعار (بالإضافة إلى تنفيذ أي مهمة أخرى قد نريد تنفيذها).

عند تلقّي رسالة، سيؤدي ذلك إلى إرسال حدث دفع في Worker الخدمة.

يجب أن يكون رمز إعداد أداة معالجة حدث الدفع مشابهًا إلى حد كبير لأي أداة استماع أخرى إلى الأحداث تكتبها في JavaScript:

self.addEventListener('push', function(event) {
    if (event.data) {
    console.log('This push event has data: ', event.data.text());
    } else {
    console.log('This push event has no data.');
    }
});

إنّ المتغيّر self هو الجزء الأكثر غرابة في هذا الرمز البرمجي بالنسبة إلى معظم المطوّرين الذين لا يتعاملون مع مهام الخدمة. يُستخدم self بشكل شائع في Web Workers، أي مشغّل الخدمات. يشير self إلى النطاق العام، مثل window في صفحة الويب. أمّا بالنسبة إلى العاملين على الويب ومشغّلي الخدمات، تشير السمة self إلى العامل نفسه.

في المثال أعلاه، يمكن اعتبار self.addEventListener() إضافة مستمع أحداث إلى عامل الخدمة نفسه.

في مثال حدث الإرسال، نتحقّق ممّا إذا كانت هناك أي بيانات ونطبع شيئًا في وحدة التحكّم.

هناك طرق أخرى يمكنك من خلالها تحليل البيانات من حدث إشعار فوري:

// Returns string
event.data.text()

// Parses data as JSON string and returns an Object
event.data.json()

// Returns blob of data
event.data.blob()

// Returns an arrayBuffer
event.data.arrayBuffer()

يستخدم معظم المستخدمين json() أو text() حسب ما يتوقعونه من تطبيقاتهم.

يوضّح هذا المثال كيفية إضافة مستمع لأحداث الإشعارات الفورية وكيفية الوصول إلى البيانات، ولكنه يفتقد إلى وظيفتَين مهمتَين جدًا. لا يتم عرض إشعار ولا يستخدم event.waitUntil().

الانتظار إلى أن

من بين الأمور التي يجب فهمها حول مشغّلات الخدمات أنّه لا يمكنك التحكّم كثيرًا في وقت تنفيذ رمز مشغّل الخدمة. ويحدِّد المتصفّح وقت تنشيطها ووقت إيقافها. الطريقة الوحيدة التي يمكنك من خلالها إعلام المتصفّح بعبارة "مرحبًا، أنا مشغول جدًا بتنفيذ إجراءات مهمة"، هي أن تَعدك بذلك عبر اتّباع طريقة event.waitUntil(). بهذه الطريقة، سيبقي المتصفّح مشغّل الخدمة قيد التشغيل إلى أن يتم حلّ الوعد الذي تم تمريره.

في أحداث الإشعارات الفورية، هناك شرط إضافي يقضي بضرورة عرض إشعار قبل أن يتمّ حلّ الوعد الذي تمّ تمريره.

في ما يلي مثال أساسي لعرض إشعار:

self.addEventListener('push', function(event) {
    const promiseChain = self.registration.showNotification('Hello, World.');

    event.waitUntil(promiseChain);
});

إنّ طلب الرقم self.registration.showNotification() هو الطريقة التي تعرض إشعارًا للمستخدم وتعرض وعدًا سيحلّ بعد عرض الإشعار.

للحفاظ على وضوح هذا المثال قدر الإمكان، لقد خصّصت هذا الوعد لvariabile بعنوان promiseChain. ويتم بعد ذلك نقل هذا الإجراء إلى event.waitUntil(). أعلم أن هذا مطول للغاية، لكنني رأيت عددًا من المشكلات التي تبلورت نتيجة سوء فهم ما يجب إرساله إلى waitUntil() أو نتيجة عدم التزام سلاسل الوعود.

في ما يلي مثال أكثر تعقيدًا يتضمن طلب شبكة للحصول على البيانات وتتبُّع حدث الإرسال باستخدام تحليلات:

self.addEventListener('push', function(event) {
    const analyticsPromise = pushReceivedTracking();
    const pushInfoPromise = fetch('/api/get-more-data')
    .then(function(response) {
        return response.json();
    })
    .then(function(response) {
        const title = response.data.userName + ' says...';
        const message = response.data.message;

        return self.registration.showNotification(title, {
        body: message
        });
    });

    const promiseChain = Promise.all([
    analyticsPromise,
    pushInfoPromise
    ]);

    event.waitUntil(promiseChain);
});

في ما يلي نُطلِق دالة تُعرِض وعدًا pushReceivedTracking()، يمكننا التظاهر، لأغراض المثال، بأنّه سيُجري طلب شبكة لمقدّم خدمة الإحصاءات. نُجري أيضًا طلبًا على الشبكة، ونحصل على الردّ ونعرض إشعارًا باستخدام بيانات الردود للعنوان ورسالة الإشعار.

يمكننا ضمان استمرار عمل الخدمة أثناء تنفيذ هاتين المهمتَين من خلال دمج هذه الوعود مع Promise.all(). يتم تمرير الوعد الناتج إلى event.waitUntil() ، ما يعني أنّ المتصفّح سينتظر حتى تنتهي كلتا الوعود قبل التحقّق من أنّه تم عرض إشعار وإيقاف عامل الخدمة.

إنّ سبب اهتمامنا بـ waitUntil() وكيفية استخدامه هو أنّ إحدى الصعوبات الأكثر شيوعًا التي يواجهها المطوّرون هي أنّ Chrome سيُظهر إعلامًا "تلقائيًا" عند عدم صحة سلسلة الوعد أو تعطّلها:

صورة للإشعار التلقائي في Chrome

سيعرض Chrome الإشعار "تم تحديث هذا الموقع الإلكتروني في الخلفية" فقط. عند تلقّي رسالة فورية، ولا يعرض حدث الدفع في مشغّل الخدمات إشعارًا بعد انتهاء الوعد الذي تم تمريره إلى event.waitUntil().

والسبب الرئيسي الذي يؤدي إلى رصد المطوّرين هو أنّ رمزهم البرمجي سيُجري غالبًا طلبًا للقيمة self.registration.showNotification() ولكنّهم لا يستخدمون أيًا من القيم التي يعرضها. ويؤدي ذلك إلى ظهور الإشعار التلقائي بشكل متقطع. على سبيل المثال، يمكننا إزالة الإرجاع لـ self.registration.showNotification() في المثال أعلاه، ونخاطر بظهور هذا الإشعار.

self.addEventListener('push', function(event) {
    const analyticsPromise = pushReceivedTracking();
    const pushInfoPromise = fetch('/api/get-more-data')
    .then(function(response) {
        return response.json();
    })
    .then(function(response) {
        const title = response.data.userName + ' says...';
        const message = response.data.message;

        self.registration.showNotification(title, {
        body: message
        });
    });

    const promiseChain = Promise.all([
    analyticsPromise,
    pushInfoPromise
    ]);

    event.waitUntil(promiseChain);
});

يمكنك أن تتفهّم مدى سهولة تفويت هذه الخطوة.

إذا ظهر لك هذا الإشعار، تحقّق من سلاسل الوعد وevent.waitUntil().

في القسم التالي، سنلقي نظرة على الإجراءات التي يمكننا اتّخاذها لتنسيق الإشعارات و المحتوى الذي يمكننا عرضه.

الخطوات التالية

الدروس التطبيقية حول الترميز