iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 16
1
Modern Web

你應該要知道的新一代Web技術---漸進式網頁(PWA)系列 第 16

[Day16] 使用IndexedDB暫存Dynamic Data(Part3)

昨天已經成功地將firebase裡的dynamic data儲存至indexedDB了,接下來因為我目前使用的cache strategies是「cache then network」,一開始是會先到cache或是indexedDB來獲取資源的。

所以讓我們來看一下要如何在feed.js裡來讀取indexedDB內的資料 /images/emoticon/emoticon43.gif

首先,我會在utility.js中,新增一個function:(流程基本上與寫入相同,只是最後是呼叫getAll() method)

function readAllData(objectStore) {
    return dbPromise.then(function(db) {
        var tx = db.transaction(objectStore, 'readonly');
        var store = tx.objectStore(objectStore);
        return store.getAll();
    });
}

接下來要注意的是,為了在feed.js也要能使用indexedDB第三方套件和我所寫的utility.js,記得要在index.html中導入。

這裡要開始修改在feed.js中的cache then network strategies的程式碼:

var url = 'https://trip-diary-f56de.firebaseio.com/posts.json';
var networkDataReceived = false;

fetch(url).then(function(res) {
    return res.json();
  }).then(function(data) {
    networkDataReceived = true;
    console.log('From Web', data);
    var dataArray = [];
    for(var key in data) {
      dataArray.push(data[key]);
    }
    updateUI(dataArray);
  });

if('indexedDB' in window) {
  readAllData('posts').then(function(data) {
    if(!networkDataReceived) {
      console.log('From IndexedDB', data);
      updateUI(data);
    }
  });
}

可以看到我將原本到cache裡尋找資源的部分,改成在indexedDB中呼叫readAllData() function,把indexedDB中的資料以一個陣列的方式回傳。最後透過updateUI() function將這些貼文資料更新到前端。


這裡還有一個地方需要修改,有的人可能會發現,當今天我在firebase又多增加了幾篇貼文後,OK!!在我的PWA中一切好像都是正常更新DER。

但是當我刪除firebase裡的某一則貼文,雖然前端顯示會不見,好像一切都是正常的。不過在indexedDB中還是會發現那則貼文是存在的。之所以這樣是因為我們是使用cache then network strategies,後來從網路fetch回來的data會overwrite前端的內容。

不過當用戶在離線狀態下,就會直接從indexedDB中來獲取貼文資訊,結果那責備我刪除的貼文又跑出來了啦QQ

這裡我的解決方法是在service worker中,每當從firebase fetch回貼文後都先「全部清除indexedDB」,之後再將最新的貼文儲存到indexedDB裡。

先在utility.js中實作清除indexedDB的方法:

function clearAllData(objectStore) {
    return dbPromise.then(function(db) {
        var tx = db.transaction(objectStore, 'readwrite');
        var store = tx.objectStore(objectStore);
        store.clear();   // 全部清除indexedDB中的資料
        return tx.complete;
    })
}

接著來看一下在sw.js中我更動的code:

if(event.request.url.indexOf(url) > -1) {
        event.respondWith(
            fetch(event.request).then(function(res) {
                var clonedRes = res.clone();
                clearAllData('posts').then(function() {   // 先清除indexedDB
                    return clonedRes.json();
                }).then(function(data) {
                    for(var key in data) {
                        writeData('posts', data[key]);   // 再寫入新的data
                    }
                });
                return res;
            })
        );
} .... 以下省略 ....

實作到這裡,我的PWA中indexedDB的部分就告一段落了 /images/emoticon/emoticon02.gif

總結一下針對PWA中的離線暫存,我這裡是將indexedDB應用到之前所學的「cache then network strategies」中,來暫存用戶經常會新增或刪除的dynamic data(json格式)。至於其他Application shell中的靜態資源或是其他用戶可能會訪問到的html、css、js和image檔案就交給Cache Storage來暫存。

Day16 結束!! /images/emoticon/emoticon42.gif


上一篇
[Day15] 使用indexedDB暫存Dynamic Data(Part2)
下一篇
[Day17] PWA中不可或缺的響應式網頁設計(Part1)
系列文
你應該要知道的新一代Web技術---漸進式網頁(PWA)29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言