當您傳送資料至網路伺服器時,有時可能會失敗。這項服務 這可能是因為使用者失去連線,也可能是 伺服器停止運作;無論是哪種方法 可以再說一次
全新 BackgroundSync API
是解決問題的最佳解決方案當 Service Worker 偵測到
網路要求失敗,註冊接收 sync
事件,
當瀏覽器認為連線已恢復時,就會傳遞這個訊息。
請注意,即使在使用者離開
,因此效果比傳統方法
重試失敗的要求。
Workbox 背景同步處理功能讓您可以更輕鬆地 BackgroundSync API,並將其用途與其他 Workbox 模組整合。這項服務 並針對尚未實作的瀏覽器,執行備用策略 BackgroundSync。
如果瀏覽器支援 BackgroundSync API,就會自動重播 代替您管理 由瀏覽器管理的間隔 在兩次重播之間 可能產生指數輪詢使用以下瀏覽器時, 並未原生支援 BackgroundSync API,Workbox 背景同步處理功能會將 自動重播。
基本用法
想要使用背景同步處理功能,最簡單的方法是使用會變更應用程式的 Plugin
自動將失敗的要求排入佇列,並在日後 sync
時重試
就會觸發這個事件
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
maxRetentionTime: 24 * 60, // Retry for max of 24 Hours (specified in minutes)
});
registerRoute(
/\/api\/.*\/*.json/,
new NetworkOnly({
plugins: [bgSyncPlugin],
}),
'POST'
);
BackgroundSyncPlugin
掛鉤
fetchDidFail
外掛程式回呼,以及
只有在擲回例外狀況時,系統才會叫用 fetchDidFail
,這很可能是
導致網路故障這表示如果系統擷取到某個值
已收到回覆,並包含
4xx
或 5xx
錯誤狀態。
如要重試所有產生的要求 (例如 5xx
狀態)。
方法是
新增 fetchDidSucceed
外掛程式
共同改善策略:
const statusPlugin = {
fetchDidSucceed: ({response}) => {
if (response.status >= 500) {
// Throwing anything here will trigger fetchDidFail.
throw new Error('Server error.');
}
// If it's not 5xx, use the response as-is.
return response;
},
};
// Add statusPlugin to the plugins array in your strategy.
進階用法
Workbox 背景同步處理功能也提供 Queue
類別,您可以
將失敗的要求例項化並新增至失敗的要求。失敗的要求會儲存
(位於 IndexedDB 中)
並在瀏覽器認為連線恢復時重試 (即
匯入同步處理事件時)。
建立佇列
如要建立工作箱背景同步佇列,您必須使用 佇列名稱 (在 origin):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
佇列名稱會做為取得標籤的標記名稱的一部分
register()
版本
來自全球
SyncManager
。是
也能做為
Object Store 名稱,
建立索引
將要求新增至佇列
建立佇列執行個體後,您可將失敗的要求新增至該執行個體。
您可以透過叫用 .pushRequest()
方法新增失敗的要求。例如:
下列程式碼會擷取任何失敗的要求,並將其加到佇列中:
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
self.addEventListener('fetch', event => {
// Add in your own criteria here to return early if this
// isn't a request that should use background sync.
if (event.request.method !== 'POST') {
return;
}
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({request: event.request});
return error;
}
};
event.respondWith(bgSyncLogic());
});
將要求加入佇列後,系統會在
Service Worker 收到 sync
事件 (在瀏覽器或
則表示連線恢復了)。如果瀏覽器不支援
BackgroundSync API 每次執行服務工作時,都會重試佇列
啟動。這需要控制 Service Worker 的網頁
所以成效有限
測試 Workbox 背景同步處理
不過在測試 BackgroundSync 時難免有直觀而困難
測試實作的最佳做法是:
- 載入網頁並註冊 Service Worker。
- 關閉電腦的網路或關閉網路伺服器。
- 請勿使用 Chrome 離線版本。下拉式選單中的離線核取方塊 開發人員工具只會影響來自該網頁的要求。Service Worker 要求 繼續播放
- 使用 Workbox 背景同步功能發出應排入佇列的網路要求。
- 如要確認要求已排入佇列,您可以查看
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
- 如要確認要求已排入佇列,您可以查看
- 現在請開啟網路或網路伺服器。
如要強制執行早期
sync
事件,請前往Chrome DevTools > Application > Service Workers
,輸入workbox-background-sync:<your queue name>
的<your queue name>
位置 您設定的佇列名稱,然後按一下「同步」按鈕。您應該會看到網路要求處理失敗的要求, 由於要求已 成功重播
類型
BackgroundSyncPlugin
實作 fetchDidFail
生命週期回呼的類別。如此一來
將失敗的要求加入背景同步佇列。
屬性
-
建構函式
void
constructor
函式如下所示:(name: string, options?: QueueOptions) => {...}
-
名稱
字串
-
選項
QueueOptions 選用
-
returns
-
Queue
這個類別可管理在 IndexedDB 中儲存失敗的要求,以及進行重試 儲存和重播程序的所有部分都可以透過 回呼函式。
屬性
-
建構函式
void
使用指定的選項建立佇列執行個體
constructor
函式如下所示:(name: string, options?: QueueOptions) => {...}
-
名稱
字串
這個佇列的專屬名稱。此名稱必須是 是專門用來登錄同步處理事件和儲存要求, 。如果發生以下情況,系統將擲回錯誤 就會偵測到重複的名稱。
-
選項
QueueOptions 選用
-
returns
-
-
名稱
字串
-
getAll
void
傳回所有尚未過期的項目 (每個
maxRetentionTime
)。 所有過期的項目都會從佇列中移除。getAll
函式如下所示:() => {...}
-
returns
Promise<QueueEntry[]>
-
-
popRequest
void
移除並傳回佇列中的最後一個要求 (及 時間戳記與任何中繼資料)。傳回的物件採用以下格式:
{request, timestamp, metadata}
。popRequest
函式如下所示:() => {...}
-
returns
Promise<QueueEntry>
-
-
pushRequest
void
將傳送的要求儲存在 IndexedDB 中 (及其時間戳記和 中繼資料),
pushRequest
函式如下所示:(entry: QueueEntry) => {...}
-
項目
QueueEntry
-
returns
承諾<void>
-
-
registerSync
void
使用這個執行個體專屬的標記註冊同步處理事件。
registerSync
函式如下所示:() => {...}
-
returns
承諾<void>
-
-
replayRequests
void
反覆執行佇列中的每個要求,並嘗試重新擷取。 如果有任何要求無法重新擷取,系統會將其移回 佇列 (為下一個同步處理事件註冊重試)。
replayRequests
函式如下所示:() => {...}
-
returns
承諾<void>
-
-
shiftRequest
void
移除並傳回佇列中的第一個要求 (以及其 時間戳記與任何中繼資料)。傳回的物件採用以下格式:
{request, timestamp, metadata}
。shiftRequest
函式如下所示:() => {...}
-
returns
Promise<QueueEntry>
-
-
大小
void
傳回佇列中的項目數量。 請注意,過期項目 (依
maxRetentionTime
) 也包括在內。size
函式如下所示:() => {...}
-
returns
Promise<number>
-
-
unshiftRequest
void
將傳送的要求儲存在 IndexedDB 中 (及其時間戳記和 。
unshiftRequest
函式如下所示:(entry: QueueEntry) => {...}
-
項目
QueueEntry
-
returns
承諾<void>
-
QueueOptions
屬性
-
forceSyncFallback
布林值 選填
-
maxRetentionTime
編號 選填
-
OnSync
OnSyncCallback 選用
QueueStore
一種類別,用於管理 IndexedDB 中佇列儲存要求。 並以佇列名稱編入索引,以便更方便存取
大部分的開發人員不需要直接存取這個類別; 但適合進階用途
屬性
-
建構函式
void
建立這個執行個體與佇列執行個體的關聯,讓新增的項目可以 以藉由佇列名稱識別
constructor
函式如下所示:(queueName: string) => {...}
-
queueName
字串
-
returns
-
-
deleteEntry
void
刪除指定 ID 的項目。
警告:這個方法不會確保刪除的項目屬於此情況 佇列 (即與
queueName
相符)。不過,這類限制是可以接受的 因為這個類別不會公開進行額外檢查 這個方法會比執行速度更快deleteEntry
函式如下所示:(id: number) => {...}
-
id
數字
-
returns
承諾<void>
-
-
getAll
void
傳回儲存庫中與
queueName
相符的所有項目。getAll
函式如下所示:() => {...}
-
returns
Promise<QueueStoreEntry[]>
-
-
popEntry
void
移除並傳回佇列中與
queueName
相符的最後一個項目。popEntry
函式如下所示:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
pushEntry
void
附加佇列中的最後一個項目。
pushEntry
函式如下所示:(entry: UnidentifiedQueueStoreEntry) => {...}
-
項目
UnidentifiedQueueStoreEntry
-
returns
承諾<void>
-
-
shiftEntry
void
移除並傳回佇列中與
queueName
相符的第一個項目。shiftEntry
函式如下所示:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
大小
void
傳回儲存庫中與
queueName
相符的項目數量。size
函式如下所示:() => {...}
-
returns
Promise<number>
-
-
unshiftEntry
void
請先在佇列中前置一個項目。
unshiftEntry
函式如下所示:(entry: UnidentifiedQueueStoreEntry) => {...}
-
項目
UnidentifiedQueueStoreEntry
-
returns
承諾<void>
-
StorableRequest
類別,方便將要求序列化與還原序列化,使要求 可能會出現在 IndexedDB 中
大部分的開發人員不需要直接存取這個類別; 但適合進階用途
屬性
-
建構函式
void
接受可用於建構模型的要求資料物件
Request
,但也可以儲存在 IndexedDB 中。constructor
函式如下所示:(requestData: RequestData) => {...}
-
requestData
RequestData
要求資料的物件,其中包含
url
加上下列任何相關屬性: [requestInit]https://fetch.spec.whatwg.org/#requestinit
。
-
returns
-
-
clone
void
建立並傳回執行個體的深度複製。
clone
函式如下所示:() => {...}
-
returns
-
-
toObject
void
傳回例項
_requestData
物件的深度複製。toObject
函式如下所示:() => {...}
-
returns
RequestData
-
-
toRequest
void
將此例項轉換為要求。
toRequest
函式如下所示:() => {...}
-
returns
要求
-
-
fromRequest
void
將 Request 物件轉換為可結構化的純物件 複製或 JSON 字串。
fromRequest
函式如下所示:(request: Request) => {...}
-
申請。
要求
-
returns
Promise<StorableRequest>
-