أحداث الدفع

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

حدث الإشعارات الفورية

عند تلقّي رسالة، سيؤدي ذلك إلى إرسال حدث دفع في 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 بشكل شائع في مشغّلات الويب، التي هي مشغّل خدمات. يشير العنصر 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().

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

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

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