Khi bạn gửi dữ liệu đến một máy chủ web, đôi khi yêu cầu sẽ không thành công. Nó có thể là do người dùng đã mất kết nối hoặc máy chủ không hoạt động; Trong cả hai trường hợp, bạn thường muốn thử gửi các yêu cầu sau.
BackgroundSync API mới
là một giải pháp lý tưởng cho vấn đề này. Khi một trình chạy dịch vụ phát hiện thấy một
yêu cầu mạng không thành công, nó có thể đăng ký để nhận sự kiện sync
,
sẽ được phân phối khi trình duyệt cho rằng kết nối đã được trả lại.
Xin lưu ý rằng sự kiện đồng bộ hoá có thể được gửi ngay cả khi người dùng đã rời khỏi
, giúp phương pháp này hiệu quả hơn nhiều so với phương pháp truyền thống là
thử lại các yêu cầu không thành công.
Tính năng Đồng bộ hoá nền Workbox được thiết kế để giúp người dùng dễ dàng sử dụng API PlatformSync và tích hợp cách sử dụng API này với các mô-đun Workbox khác. Nó đồng thời triển khai chiến lược dự phòng cho các trình duyệt chưa triển khai Đồng bộ hoá trong nền.
Các trình duyệt hỗ trợ API BackgroundSync sẽ tự động phát lại không thành công thay mặt bạn tại khoảng thời gian do trình duyệt quản lý, có thể sử dụng thuật toán thời gian đợi luỹ thừa giữa các lần phát lại. Trong các trình duyệt không hỗ trợ sẵn API BackgroundSync, tính năng Đồng bộ hoá nền Workbox sẽ tự động thử phát lại bất cứ khi nào trình chạy dịch vụ của bạn khởi động.
Cách sử dụng cơ bản
Cách dễ nhất để sử dụng tính năng Đồng bộ hoá trong nền là dùng Plugin
tự động xếp các yêu cầu không thành công vào hàng đợi và thử lại khi sync
trong tương lai
kích hoạt các sự kiện.
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
móc vào
Lệnh gọi lại trình bổ trợ fetchDidFail
và
fetchDidFail
chỉ được gọi nếu có một ngoại lệ được gửi, rất có thể là do
do lỗi mạng. Điều này có nghĩa là yêu cầu sẽ không được thử lại nếu có
đã nhận được phản hồi
Trạng thái lỗi 4xx
hoặc 5xx
.
Nếu bạn muốn thử lại tất cả các yêu cầu dẫn đến kết quả như trạng thái 5xx
,
bạn có thể làm như vậy bằng cách
thêm một trình bổ trợ fetchDidSucceed
cho chiến lược của mình:
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.
Cách sử dụng nâng cao
Tính năng Đồng bộ hoá nền Workbox cũng cung cấp lớp Queue
mà bạn có thể
tạo thực thể và thêm các yêu cầu không thành công. Hệ thống sẽ lưu trữ các yêu cầu không thực hiện được
trong IndexedDB
và được thử lại khi trình duyệt cho rằng kết nối đã được khôi phục (ví dụ:
khi nhận được sự kiện đồng bộ hoá).
Tạo hàng đợi
Để tạo Hàng đợi đồng bộ hoá trong nền Hộp công việc, bạn cần tạo hàng đợi này bằng tên hàng đợi (phải là tên duy nhất cho origin):
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
Tên hàng đợi được sử dụng như một phần của tên thẻ để nhận
Tập register()
do các nhà xuất bản
SyncManager
. Bây giờ
cũng được dùng làm thuộc tính
Tên Lưu trữ đối tượng cho
cơ sở dữ liệu IndexedDB.
Thêm một yêu cầu vào Hàng đợi
Sau khi tạo phiên bản Hàng đợi, bạn có thể thêm các yêu cầu không thực hiện được vào đó.
Bạn không thêm được yêu cầu không thành công bằng cách gọi phương thức .pushRequest()
. Ví dụ:
đoạn mã sau đây nắm bắt mọi yêu cầu không thành công và thêm chúng vào hàng đợi:
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());
});
Sau khi được thêm vào hàng đợi, yêu cầu sẽ được tự động thử lại khi
Service worker nhận sự kiện sync
(xảy ra khi trình duyệt
cho rằng kết nối đã được khôi phục). Trình duyệt không hỗ trợ thẻ
PlatformSync API sẽ thử lại hàng đợi mỗi khi trình chạy dịch vụ được
đã khởi động. Điều này yêu cầu trang kiểm soát trình chạy dịch vụ phải
nên hoạt động thử nghiệm sẽ không hiệu quả bằng.
Kiểm thử tính năng đồng bộ hoá dưới nền hộp làm việc
Tiếc là việc thử nghiệm ứng dụng BackgroundSync có phần không trực quan và khó khăn vì một số lý do.
Cách tốt nhất để kiểm thử kết quả triển khai là thực hiện những việc sau:
- Tải một trang lên và đăng ký trình chạy dịch vụ của bạn.
- Tắt mạng máy tính hoặc tắt máy chủ web của bạn.
- KHÔNG SỬ DỤNG NGOẠI TUYẾN CHROME DEVTOOLS NGOẠI TUYẾN. Hộp đánh dấu ngoại tuyến trong Công cụ cho nhà phát triển chỉ ảnh hưởng đến các yêu cầu từ trang. Yêu cầu của Trình chạy dịch vụ sẽ tiếp tục được lưu trữ.
- Thực hiện các yêu cầu mạng cần được đưa vào hàng đợi bằng tính năng Đồng bộ hoá nền hộp làm việc.
- Bạn có thể kiểm tra để biết các yêu cầu đã được đưa vào hàng đợi hay chưa bằng cách xem trong
Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
- Bạn có thể kiểm tra để biết các yêu cầu đã được đưa vào hàng đợi hay chưa bằng cách xem trong
- Bây giờ, hãy bật mạng hoặc máy chủ web của bạn.
Buộc thực hiện một sự kiện sớm
sync
bằng cách chuyển đếnChrome DevTools > Application > Service Workers
, nhập tên thẻ củaworkbox-background-sync:<your queue name>
, trong đó<your queue name>
phải là tên của hàng đợi bạn đặt, sau đó nhấp vào nút 'Đồng bộ hoá' .Bạn sẽ thấy các yêu cầu kết nối mạng được thực hiện đối với các yêu cầu không thành công và dữ liệu IndexedDB hiện đang trống vì các yêu cầu đã được đã phát lại thành công.
Loại
BackgroundSyncPlugin
Một lớp triển khai phương thức gọi lại trong vòng đời fetchDidFail
. Điều này giúp
dễ dàng hơn trong việc thêm các yêu cầu không thành công vào Hàng đợi đồng bộ hoá dưới nền.
Thuộc tính
-
hàm khởi tạo
void
Hàm
constructor
có dạng như sau:(name: string, options?: QueueOptions) => {...}
-
tên
string
Xem
workbox-background-sync.Queue
tài liệu để biết thông tin chi tiết về tham số. -
tùy chọn
QueueOptions không bắt buộc
-
returns
-
Queue
Một lớp để quản lý việc lưu trữ các yêu cầu không thành công trong IndexedDB và thử lại các yêu cầu đó sau. Tất cả các phần của quá trình lưu trữ và phát lại đều có thể quan sát thông qua lệnh gọi lại.
Thuộc tính
-
hàm khởi tạo
void
Tạo một bản sao của Hàng đợi với các tuỳ chọn cho sẵn
Hàm
constructor
có dạng như sau:(name: string, options?: QueueOptions) => {...}
-
tên
string
Tên duy nhất cho hàng đợi này. Tên này phải duy nhất vì nó được dùng để đăng ký các sự kiện đồng bộ hoá và các yêu cầu lưu trữ trong IndexedDB dành riêng cho trường hợp này. Hệ thống sẽ gửi thông báo lỗi nếu đã phát hiện thấy tên trùng lặp.
-
tùy chọn
QueueOptions không bắt buộc
-
returns
-
-
tên
string
-
getAll
void
Trả về tất cả các mục chưa hết hạn (mỗi
maxRetentionTime
). Mọi mục nhập đã hết hạn sẽ bị xoá khỏi hàng đợi.Hàm
getAll
có dạng như sau:() => {...}
-
returns
Promise<QueueEntry[]>
-
-
popRequest
void
Xoá và trả về yêu cầu gần đây nhất trong hàng đợi (cùng với và bất kỳ siêu dữ liệu nào). Đối tượng được trả về có dạng:
{request, timestamp, metadata}
.Hàm
popRequest
có dạng như sau:() => {...}
-
returns
Promise<QueueEntry>
-
-
pushRequest
void
Lưu trữ yêu cầu đã truyền trong IndexedDB (cùng với dấu thời gian và bất kỳ siêu dữ liệu) ở cuối hàng đợi.
Hàm
pushRequest
có dạng như sau:(entry: QueueEntry) => {...}
-
mục nhập
QueueEntry
-
returns
Lời hứa<vô hiệu>
-
-
registerSync
void
Đăng ký một sự kiện đồng bộ hoá bằng thẻ dành riêng cho trường hợp này.
Hàm
registerSync
có dạng như sau:() => {...}
-
returns
Lời hứa<vô hiệu>
-
-
replayRequests
void
Lặp lại từng yêu cầu trong hàng đợi và cố gắng tìm nạp lại yêu cầu đó. Nếu bất kỳ yêu cầu nào không thể tìm nạp lại, yêu cầu đó sẽ được đặt lại về cùng một vị trí trong hàng đợi (đăng ký lần thử lại cho sự kiện đồng bộ hoá tiếp theo).
Hàm
replayRequests
có dạng như sau:() => {...}
-
returns
Lời hứa<vô hiệu>
-
-
shiftRequest
void
Xoá và trả về yêu cầu đầu tiên trong hàng đợi (cùng với và bất kỳ siêu dữ liệu nào). Đối tượng được trả về có dạng:
{request, timestamp, metadata}
.Hàm
shiftRequest
có dạng như sau:() => {...}
-
returns
Promise<QueueEntry>
-
-
size
void
Trả về số lượng mục nhập có trong hàng đợi. Xin lưu ý rằng các mục nhập đã hết hạn (mỗi
maxRetentionTime
) cũng được tính vào số lượng này.Hàm
size
có dạng như sau:() => {...}
-
returns
Promise<number>
-
-
unshiftRequest
void
Lưu trữ yêu cầu đã truyền trong IndexedDB (cùng với dấu thời gian và bất kỳ siêu dữ liệu) ở đầu hàng đợi.
Hàm
unshiftRequest
có dạng như sau:(entry: QueueEntry) => {...}
-
mục nhập
QueueEntry
-
returns
Lời hứa<vô hiệu>
-
QueueOptions
Thuộc tính
-
forceSyncFallback
boolean không bắt buộc
-
maxRetentionTime
số không bắt buộc
-
onSync
OnSyncCallback không bắt buộc
QueueStore
Một lớp để quản lý việc lưu trữ các yêu cầu từ Hàng đợi trong IndexedDB, được lập chỉ mục theo tên hàng đợi để truy cập dễ dàng hơn.
Hầu hết các nhà phát triển không cần truy cập trực tiếp vào lớp này; nó được hiển thị cho các trường hợp sử dụng nâng cao.
Thuộc tính
-
hàm khởi tạo
void
Liên kết thực thể này với một thực thể Hàng đợi để các mục nhập được thêm có thể được được xác định theo tên hàng đợi.
Hàm
constructor
có dạng như sau:(queueName: string) => {...}
-
queueName
string
-
returns
-
-
deleteEntry
void
Xoá mục nhập theo mã nhận dạng đã cho.
CẢNH BÁO: phương pháp này không đảm bảo mục nhập đã xoá thuộc về hàng đợi (tức là khớp với
queueName
). Tuy nhiên, giới hạn này có thể chấp nhận được vì lớp học này không được hiển thị công khai. Việc kiểm tra bổ sung sẽ giúp phương thức này chậm hơn mức cần thiết.Hàm
deleteEntry
có dạng như sau:(id: number) => {...}
-
id
số
-
returns
Lời hứa<vô hiệu>
-
-
getAll
void
Trả về tất cả các mục nhập trong cửa hàng khớp với
queueName
.Hàm
getAll
có dạng như sau:() => {...}
-
returns
Promise<QueueStoreEntry[]>
-
-
popEntry
void
Xoá và trả về mục nhập cuối cùng trong hàng đợi khớp với
queueName
.Hàm
popEntry
có dạng như sau:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
pushEntry
void
Thêm một mục nhập cuối cùng vào hàng đợi.
Hàm
pushEntry
có dạng như sau:(entry: UnidentifiedQueueStoreEntry) => {...}
-
mục nhập
UnidentifiedQueueStoreEntry
-
returns
Lời hứa<vô hiệu>
-
-
shiftEntry
void
Xoá và trả về mục nhập đầu tiên trong hàng đợi khớp với
queueName
.Hàm
shiftEntry
có dạng như sau:() => {...}
-
returns
Promise<QueueStoreEntry>
-
-
size
void
Trả về số lượng mục nhập trong cửa hàng khớp với
queueName
.Hàm
size
có dạng như sau:() => {...}
-
returns
Promise<number>
-
-
unshiftEntry
void
Thêm một mục vào trước trong hàng đợi.
Hàm
unshiftEntry
có dạng như sau:(entry: UnidentifiedQueueStoreEntry) => {...}
-
mục nhập
UnidentifiedQueueStoreEntry
-
returns
Lời hứa<vô hiệu>
-
StorableRequest
Một lớp giúp dễ dàng chuyển đổi tuần tự và giải trình tự các yêu cầu để chúng có thể được lưu trữ trong IndexedDB.
Hầu hết các nhà phát triển không cần truy cập trực tiếp vào lớp này; nó được hiển thị cho các trường hợp sử dụng nâng cao.
Thuộc tính
-
hàm khởi tạo
void
Chấp nhận một đối tượng của dữ liệu yêu cầu có thể dùng để tạo
Request
nhưng cũng có thể được lưu trữ trong IndexedDB.Hàm
constructor
có dạng như sau:(requestData: RequestData) => {...}
-
requestData
RequestData
Đối tượng của dữ liệu yêu cầu bao gồm
url
và mọi thuộc tính có liên quan của [requestInit]https://fetch.spec.whatwg.org/#requestinit
.
-
returns
-
-
sao chép
void
Tạo và trả về một bản sao sâu của thực thể.
Hàm
clone
có dạng như sau:() => {...}
-
returns
-
-
toObject
void
Trả về một bản sao sâu của đối tượng
_requestData
của thực thể.Hàm
toObject
có dạng như sau:() => {...}
-
returns
RequestData
-
-
toRequest
void
Chuyển đổi thực thể này thành một Yêu cầu.
Hàm
toRequest
có dạng như sau:() => {...}
-
returns
Yêu cầu
-
-
fromRequest
void
Chuyển đổi đối tượng Yêu cầu thành một đối tượng thuần tuý có thể có cấu trúc được sao chép hoặc xâu chuỗi JSON.
Hàm
fromRequest
có dạng như sau:(request: Request) => {...}
-
request
Yêu cầu
-
returns
Promise<StorableRequest>
-