เหตุการณ์พุช

เมื่อถึงจุดนี้ เราจะพูดถึงการติดตามผู้ใช้และการส่งข้อความพุช ขั้นตอนถัดไปคือการรับข้อความ Push นี้ในอุปกรณ์ของผู้ใช้และแสดงการแจ้งเตือน (รวมถึงทํางานอื่นๆ ที่เราอาจต้องการทํา)

เหตุการณ์ Push

เมื่อได้รับข้อความ ระบบจะส่งออกเหตุการณ์พุชใน Service Worker ของคุณ

โค้ดสำหรับการตั้งค่า Listener เหตุการณ์พุชควรคล้ายกับโปรแกรมฟังเหตุการณ์อื่นๆ ที่คุณจะเขียนใน 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.');
    }
});

ส่วนที่แปลกที่สุดของโค้ดนี้สำหรับนักพัฒนาแอปส่วนใหญ่ที่เพิ่งเริ่มใช้ Service Worker คือตัวแปร self self มักใช้ใน Web Worker ซึ่งเป็น Service Worker self หมายถึงขอบเขตส่วนกลาง ซึ่งคล้ายกับ window ในหน้าเว็บ แต่สำหรับ Web Worker และ Service Worker self จะหมายถึงตัวผู้ปฏิบัติงาน

ในตัวอย่างข้างต้น self.addEventListener() เปรียบเสมือนการเพิ่มโปรแกรมรับเหตุการณ์ไปยัง Service Worker เอง

ในตัวอย่างเหตุการณ์ Push เราจะตรวจสอบว่ามีข้อมูลหรือไม่และพิมพ์ข้อมูลบางอย่างไปยังคอนโซล

คุณสามารถแยกวิเคราะห์ข้อมูลจากเหตุการณ์ Push ได้ด้วยวิธีอื่นๆ ดังนี้

// 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() โดยขึ้นอยู่กับสิ่งที่คาดหวังจากแอปพลิเคชัน

ตัวอย่างนี้แสดงวิธีเพิ่ม Listener เหตุการณ์ Push และวิธีเข้าถึงข้อมูล แต่ไม่มีฟังก์ชันการทำงานที่สำคัญ 2 อย่าง ระบบไม่แสดงการแจ้งเตือน และไม่ได้ใช้ประโยชน์จาก event.waitUntil()

รอจนกว่า

สิ่งหนึ่งที่ควรทราบเกี่ยวกับ Service Worker ก็คือคุณจะควบคุมเวลาที่เรียกใช้โค้ดของ Service Worker ได้น้อยมาก เบราว์เซอร์จะตัดสินใจว่าจะปลุกให้ทำงานเมื่อใดและจะปิดตอนไหน วิธีเดียวที่คุณสามารถบอกเบราว์เซอร์ว่า "เว้ย ฉันยุ่งมากจริงๆ ที่กำลังทำเรื่องสำคัญ" คือการบอกสัญญาเพื่อใช้เมธอด event.waitUntil() ซึ่งจะทำให้เบราว์เซอร์เรียกใช้ Service Worker ต่อไปจนกว่า Promise ที่คุณส่งเข้ามาจะได้รับการแก้ไข

เหตุการณ์ Push มีข้อกําหนดเพิ่มเติมที่คุณต้องแสดงการแจ้งเตือนก่อนที่ Promise ที่ส่งเข้ามาจะได้รับการแก้ไข

ตัวอย่างพื้นฐานของการแสดงการแจ้งเตือนมีดังนี้

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

    event.waitUntil(promiseChain);
});

การเรียก self.registration.showNotification() เป็นเมธอดที่แสดงการแจ้งเตือนต่อผู้ใช้และจะแสดงผลลัพธ์เป็น Promise ที่สมบูรณ์เมื่อแสดงการแจ้งเตือนแล้ว

เราได้กำหนด Promise นี้ให้กับตัวแปรชื่อ promiseChain เพื่อให้ตัวอย่างนี้ชัดเจนที่สุด จากนั้นระบบจะส่งค่านี้ไปยัง event.waitUntil() เราทราบว่านี่เป็นเรื่องที่มีขอบเขตชัดเจนมาก แต่ฉันเคยเห็นปัญหามากมายที่เกิดจากการเข้าใจผิดว่าควรส่งผ่านไปยัง waitUntil() หรือเป็นผลจากการผูกมัดที่เสียหาย

ตัวอย่างที่ซับซ้อนมากขึ้นซึ่งมีการขอข้อมูลจากเครือข่ายและการติดตามเหตุการณ์ Push ด้วย Analytics อาจมีลักษณะดังนี้

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() ซึ่งเราจะสมมติว่าจะทำคําขอเครือข่ายไปยังผู้ให้บริการวิเคราะห์เพื่อแสดงตัวอย่าง นอกจากนี้ เรายังส่งคำขอเครือข่าย รับการตอบกลับ และแสดงการแจ้งเตือนโดยใช้ข้อมูลการตอบกลับสำหรับชื่อและข้อความของการแจ้งเตือนด้วย

เราช่วยให้มั่นใจได้ว่า Service Worker จะยังคงทำงานอยู่ขณะที่ทั้ง 2 งานนี้เสร็จสิ้นด้วยการรวมการสัญญาเหล่านี้เข้ากับ Promise.all() ระบบจะส่ง Promise ที่เป็นผลลัพธ์ไปยัง event.waitUntil() ซึ่งหมายความว่าเบราว์เซอร์จะรอจนกว่า Promise ทั้ง 2 รายการจะเสร็จสิ้นก่อนที่จะตรวจสอบว่ามีการแสดงการแจ้งเตือนและหยุดการทำงานของ Service Worker

เหตุผลที่เราควรกังวลเกี่ยวกับ waitUntil() และวิธีใช้คือหนึ่งในปัญหาที่พบบ่อยที่สุดที่นักพัฒนาซอฟต์แวร์พบคือเมื่อเชน Promise ไม่ถูกต้อง/ใช้งานไม่ได้ Chrome จะแสดงการแจ้งเตือน "เริ่มต้น" นี้

รูปภาพการแจ้งเตือนเริ่มต้นใน Chrome

Chrome จะแสดงการแจ้งเตือน "เว็บไซต์นี้ได้รับการอัปเดตในเบื้องหลัง" เมื่อได้รับข้อความ Push และเหตุการณ์ Push ใน Service Worker ไม่แสดงการแจ้งเตือนหลังจากที่ Promise ที่ส่งไปยัง 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()

ในส่วนถัดไป เราจะดูสิ่งที่ทำได้เพื่อจัดรูปแบบการแจ้งเตือนและเนื้อหาที่แสดงได้

สถานที่ที่จะไปต่อ

Codelabs