đồng bộ hoá nền hộp công việc

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ợ fetchDidFailfetchDidFail 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:

  1. Tải một trang lên và đăng ký trình chạy dịch vụ của bạn.
  2. 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ữ.
  3. 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
  4. Bây giờ, hãy bật mạng hoặc máy chủ web của bạn.
  5. Buộc thực hiện một sự kiện sớm sync bằng cách chuyển đến Chrome DevTools > Application > Service Workers, nhập tên thẻ của workbox-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á' .

    Ví dụ về nút Đồng bộ hoá trong Công cụ của Chrome cho nhà phát triển

  6. 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

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

  • 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&lt;QueueEntry[]&gt;

  • 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&lt;QueueEntry&gt;

  • 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&lt;QueueEntry&gt;

  • 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&lt;number&gt;

  • 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

  • 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&lt;QueueStoreEntry[]&gt;

  • 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&lt;QueueStoreEntry&gt;

  • 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&lt;QueueStoreEntry&gt;

  • 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&lt;number&gt;

  • 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.

  • 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:

    () => {...}

  • 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