Sự kiện đẩy

Matt Gaunt

Đến thời điểm này, chúng ta đã đề cập đến việc đăng ký người dùng và gửi thông báo đẩy. Bước tiếp theo là nhận thông báo đẩy này trên thiết bị của người dùng và hiển thị thông báo (cũng như thực hiện bất kỳ thao tác nào khác) công việc mà chúng tôi có thể muốn làm).

Sự kiện đẩy

Khi nhận được một tin nhắn, sự kiện đẩy sẽ được gửi đi trong trình chạy dịch vụ của bạn.

Mã thiết lập trình nghe sự kiện đẩy sẽ khá giống với mọi sự kiện khác trình nghe bạn muốn viết trong 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.');
    }
});

Phần kỳ lạ nhất của mã này đối với hầu hết các nhà phát triển mới làm quen với trình chạy dịch vụ là self biến. self thường được dùng trong Web Workers (Trình chạy dịch vụ). self đề cập đến phạm vi toàn cầu, đại loại như window trong một trang web. Nhưng đối với nhân viên web và nhân viên dịch vụ, self tham chiếu đến chính worker.

Trong ví dụ trên, bạn có thể coi self.addEventListener() là việc thêm trình nghe sự kiện vào chính trình chạy dịch vụ đó.

Trong ví dụ về sự kiện đẩy, chúng ta kiểm tra xem có dữ liệu nào hay không rồi xuất nội dung vào bảng điều khiển.

Có nhiều cách khác để bạn phân tích cú pháp dữ liệu trong một sự kiện đẩy:

// 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()

Hầu hết mọi người đều sử dụng json() hoặc text() tuỳ thuộc vào những gì họ mong đợi từ ứng dụng của mình.

Ví dụ này minh hoạ cách thêm trình nghe sự kiện đẩy và cách truy cập dữ liệu, nhưng thiếu hai chức năng rất quan trọng. Hiện không có thông báo và không sử dụng event.waitUntil().

Chờ đến

Một trong những điều cần hiểu về trình chạy dịch vụ là bạn có ít quyền kiểm soát đối với thời điểm mã trình chạy dịch vụ sẽ chạy. Trình duyệt quyết định thời điểm đánh thức và thời điểm chấm dứt cuộc trò chuyện đó. Cách duy nhất để bạn có thể nói với trình duyệt rằng: "Này, tôi đang bận làm việc quan trọng nội dung", là truyền lời hứa vào phương thức event.waitUntil(). Với thao tác này, trình duyệt sẽ giữ cho trình chạy dịch vụ tiếp tục chạy cho đến khi lời hứa mà bạn đã chuyển vào được thực hiện.

Với sự kiện đẩy, có một yêu cầu bổ sung là bạn phải hiển thị thông báo trước lời hứa mà bạn thực hiện đã được thực hiện.

Dưới đây là ví dụ cơ bản về việc hiển thị một thông báo:

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

    event.waitUntil(promiseChain);
});

Gọi self.registration.showNotification() là phương thức hiển thị thông báo cho người dùng và Google hứa hẹn sẽ phân giải sau khi thông báo được hiển thị.

Để đảm bảo ví dụ này rõ ràng nhất có thể, tôi đã cam kết này cho biến có tên là promiseChain. Sau đó, giá trị này được truyền vào event.waitUntil(). Tôi biết đây là rất chi tiết, nhưng tôi đã thấy một số vấn đề đã lên đến đỉnh điểm là hiểu sai thông tin nào nên được chuyển vào waitUntil() hoặc do lời hứa bị hỏng chuỗi.

Ví dụ phức tạp hơn với yêu cầu mạng cho dữ liệu và theo dõi sự kiện đẩy bằng Analytics có thể hiển thị như sau:

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);
});

Ở đây, chúng ta gọi một hàm trả về một lời hứa pushReceivedTracking() để lấy ví dụ, chúng ta có thể giả vờ sẽ tạo một yêu cầu mạng cho nhà cung cấp phân tích của chúng tôi. Chúng tôi cũng đang thực hiện một yêu cầu mạng, nhận được và hiển thị thông báo sử dụng dữ liệu phản hồi cho tiêu đề và nội dung của thông báo.

Chúng ta có thể đảm bảo worker dịch vụ vẫn hoạt động trong khi cả hai tác vụ này đều được thực hiện bằng cách kết hợp những lời hứa này với Promise.all(). Lời hứa kết quả được chuyển vào event.waitUntil() nghĩa là trình duyệt sẽ đợi cho đến khi cả hai lời hứa đã hoàn tất trước khi kiểm tra xem một thông báo đã được hiển thị và chấm dứt trình chạy dịch vụ.

Lý do chúng ta nên quan tâm về waitUntil() và cách sử dụng waitUntil() là một trong những lý do vấn đề mà các nhà phát triển thường gặp là khi chuỗi hứa hẹn không chính xác / bị hỏng, Chrome sẽ hiển thị "mặc định" này thông báo:

Hình ảnh của thông báo mặc định trong Chrome

Chrome sẽ chỉ hiển thị thông báo "Trang web này đã được cập nhật ở chế độ nền". khi một nhận được thông báo đẩy và sự kiện đẩy trong trình chạy dịch vụ không hiển thị sau khi lời hứa được chuyển đến event.waitUntil() đã hoàn tất.

Lý do chính khiến nhà phát triển gặp phải vấn đề này là mã của họ sẽ thường gọi self.registration.showNotification() nhưng chúng không thực hiện bất cứ điều gì có cam kết trả về. Việc này không liên tục dẫn đến thông báo mặc định đang được hiển thị. Ví dụ: chúng tôi có thể xoá việc trả lại hàng cho self.registration.showNotification() trong ví dụ ở trên, nên chúng ta có nguy cơ nhìn thấy thông tin này .

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);
});

Bạn có thể thấy đây là việc dễ bỏ lỡ.

Hãy nhớ rằng nếu bạn thấy thông báo đó, hãy kiểm tra chuỗi lời hứa và event.waitUntil().

Trong phần tiếp theo, chúng ta sẽ xem xét những việc chúng ta có thể làm để tạo kiểu cho thông báo và nội dung nào chúng tôi có thể hiển thị.

Điểm đến tiếp theo

Phòng thí nghiệm lập trình