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

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

เหตุการณ์ Push

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

โค้ดสําหรับการตั้งค่า Listener เหตุการณ์ Push ควรคล้ายกับ 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 ได้เพียงเล็กน้อย โดยเบราว์เซอร์จะเป็นผู้ตัดสินใจว่าจะปลุกหรือสิ้นสุดการทำงานของแท็บเมื่อใด วิธีเดียวที่จะบอกเบราว์เซอร์ว่า "ฉันยุ่งมากกับเรื่องสำคัญ" คือการส่ง Promise ไปยังเมธอด 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() หรือเกิดจาก Promise Chain ที่ไม่เป็นไปตามที่คาดไว้

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

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

ขั้นตอนถัดไป

Code labs