رویدادهای فشاری

در این مرحله، ما اشتراک یک کاربر و ارسال پیام فشار را پوشش دادیم. مرحله بعدی دریافت این پیام فشار روی دستگاه کاربر و نمایش یک اعلان است (و همچنین انجام هر کار دیگری که ممکن است بخواهیم انجام دهیم).

وقتی پیامی دریافت می‌شود، منجر به ارسال یک رویداد فشاری در سرویس‌کار شما می‌شود.

کد راه اندازی یک شنونده رویداد فشاری باید تقریباً شبیه هر شنونده رویداد دیگری باشد که در جاوا اسکریپت می نویسید:

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() را می توان به عنوان افزودن یک رویداد شنونده به خود Service Worker در نظر گرفت.

در داخل مثال رویداد فشار، بررسی می‌کنیم که آیا داده‌ای وجود دارد و چیزی را در کنسول چاپ می‌کنیم.

روش‌های دیگری نیز وجود دارد که می‌توانید داده‌ها را از یک رویداد فشار تجزیه کنید:

// 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() استفاده می کنند.

این مثال نحوه اضافه کردن یک شنونده رویداد push و نحوه دسترسی به داده ها را نشان می دهد، اما دو بخش بسیار مهم از عملکرد را از دست داده است. این اعلان نشان نمی دهد و از event.waitUntil() استفاده نمی کند.

صبر کنید تا

یکی از چیزهایی که در مورد کارگران خدمات باید درک کنید این است که کنترل کمی روی زمانی که کد سرویس‌کار قرار است اجرا شود، ندارید. مرورگر تصمیم می‌گیرد چه زمانی آن را بیدار کند و چه زمانی آن را خاتمه دهد. تنها راهی که می‌توانید به مرورگر بگویید «هی، من فوق‌العاده مشغول انجام کارهای مهم هستم» این است که یک وعده را به متد event.waitUntil() منتقل کنید. با این کار، مرورگر سرویس‌کار را تا زمانی که وعده‌ای که داده‌اید تسویه نشده است، فعال نگه می‌دارد.

با رویدادهای فشار، یک نیاز اضافی وجود دارد که باید قبل از اینکه وعده ای که داده اید تسویه شود، یک اعلان نمایش دهید.

در اینجا یک مثال اساسی از نمایش اعلان آورده شده است:

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

    event.waitUntil(promiseChain);
});

فراخوانی self.registration.showNotification() روشی است که یک اعلان را به کاربر نمایش می دهد و یک وعده را برمی گرداند که پس از نمایش اعلان برطرف می شود.

به منظور شفاف نگه داشتن این مثال تا حد امکان، من این وعده را به متغیری به نام 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 فقط «این سایت در پس‌زمینه به‌روزرسانی شده است» را نشان می‌دهد. اعلان زمانی که یک پیام فشار دریافت می شود و رویداد فشار در سرویس کارگر پس از اتمام وعده به 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);
});

می‌توانید ببینید که چگونه از دست دادن آن آسان است.

فقط به یاد داشته باشید - اگر آن اعلان را مشاهده کردید، chains و event.waitUntil() خود را بررسی کنید.

در بخش بعدی، می‌خواهیم ببینیم چه کارهایی می‌توانیم برای استایل دادن به اعلان‌ها انجام دهیم و چه محتوایی را می‌توانیم نمایش دهیم.

بعد کجا بریم

آزمایشگاه های کد